2

Strings in Java are kept around for a while, potentially a long while. This is a good thing, unless that String contains a user's actual password. Character arrays are suggested because they aren't immutable and can be cleared faster. (Let's hope there's never a "Bitter Coffee" attack that works like Heartbleed but against the JVM (remote heap dump)).

I notice that Spring Security PasswordEncoder takes a CharSequence not a String, possibly for this reason. However I'm not sure what object I should use to keep the password in memory pre-hashing. Would StringBuilder be appropriate? what would that look like? I'm even less sure if I'm creating a REST API (with Jackson under the hood, via either Spring Data or Spring MVC) how I can keep that from ever being a String.

How can I code a JSON REST API for creating/updating passwords whilst being as secure as possible and avoiding the various problems with using Strings?

Community
  • 1
  • 1
xenoterracide
  • 16,274
  • 24
  • 118
  • 243
  • 2
    Before you even get to spring security you will have to avoid the fact that most REST frameworks including spring security builtin web security retrieves the password as a request parameter ... Which is a String. – Adam Gent Jul 06 '15 at 12:08

1 Answers1

1

How can I code a JSON REST API for creating/updating passwords whilst being as secure as possible and avoiding the various problems with using Strings?

Well API keys are not true passwords. You have control on how API keys are created so you can create some random string which will have a very low collision (ie double UUID) and very low common substring (in the case of dedup). After the client logs in through the REST API using the key you could use temporary tokens thus improving the likelihood of the API key getting garbage collected.

As for dealing with real passwords which is the case for a human logging in (perhaps to reset the API key) you don't really have much options given that almost every servlet container will turn request parameters into strings. One cheesy option is to have the client through Javascript (or whatever your clients are) Base64 encode the password and then add a separator and then add a randomly generated number or string to the password. This is not really for obfuscation but again to lower the probability of keeping the same string around. You'll have to be careful of course to decode into char or byte array and then remove the random suffix by manipulating the char or byte array (see CharBuffer).

Another complicated option is the microservice cloud approach. Just make an authentication service composed of a couple of tiny round robin instances that only do authentication. Have those JVM instances get restarted frequently (to flush memory). Or if they are small enough they will hopefully garbage collect more frequently.

I'll assume of course that your data repository has salted passwords (otherwise this safety precaution is pretty moot).

To be honest though there are so many other threats that I don't really think its worth the effort for most use cases in a HTTP server environment.

The reason why Java Swing uses char[] for password because Swing is used for a desktop environment. Desktop environments are far more likely to have malicious programs such as virus/spyware that could do some memory probing for passwords.

With that in mind its really the clients you should worry about and not the server.

Adam Gent
  • 47,843
  • 23
  • 153
  • 203
  • yeah, the API's I'm building are primarily to back and user frontend written in angular or something, and my entity is currently converting via the BCryptPasswordEncoder. I kind of like your idea of what is effectively a client side salt. One could use csrfToken for that, and validate it too. let's hope there's never a remote memory attack, but I worry that features like "Java Debugger over HTTP" + "String dedup" make this more likely. Also thinking about it, may mean that we can build features in that make it less likely. – xenoterracide Jul 06 '15 at 15:21
  • Also remember that Java is not C or C++ and does not have invalid pointer arithmetic, buffer overflows etc.. So while it is still sort of bad to have passwords hanging around in memory its not as bad compared to other languages that do not have protected memory allocation. – Adam Gent Jul 06 '15 at 15:29
  • right, "my code" would never cause the problem. but Java has hotspot, and is written in C? which does have that... I'm not saying this will ever happen, but just thinking on the the what if, worst case scenario. Like heartbleed someone elses mistake... a language bug... or.. (what do you mean you turned on the debugger over http on prod with password123). Also I initially assumed this might just be a knowledge/documentation gap. – xenoterracide Jul 06 '15 at 15:38
  • 1
    Yes but it is also on a server which I hope would be rather locked down with a rather stable JVM. Really its your clients you need to worry about leaking passwords (e.g. fishing). You don't want to spend a considerable time building a huge wall in the wrong place. – Adam Gent Jul 06 '15 at 15:47