In Java, how do I extract a password from a HttpSe

2019-01-14 17:22发布

问题:

A common Java security guideline for handling sensitive data (== passwords) recommends never using a String object to store the data, and instead using an array of bytes or chars. I am trying to apply this guideline in a HttpServlet handler. In particular, I am using a basic-authentication-like approach where the credentials are passed in in a header (this is a GET request, so no body).

The issue I'm running into is that it seems impossible to get to the header data without generating a String object, which violates the guideline from the get-go. I've searched for a solution pretty thoroughly, and didn't find any relevant discussion. Does anybody have any insight into this issue?

NOTE: this takes place over HTTPS, so there is no connection security problem here.

回答1:

The simple answer is that you can't get the parameter in any other form than a String. At least, not using the standard servlet APIs. But there are a couple of possible "get outs".

  1. If you are prepared to get really ugly, you can in fact break the abstraction of the String object, and reach in and overwrite the characters. (Strings are in fact mutable if you are prepared to break the rules. This is one of the few situations where this might be justified.)

  2. There might be a nonstandard API extension in your web container's implementation of (say) HttpServletRequest for doing this. If not, you may be able to get hold of the source code and add one. (Assuming you are using an open-source web container.)


Having said that, IMO the "no strings" approach to Java security is misguided, or at least over-rated in terms of what it achieves.

The "no strings" approach guards against the possibility that something can trawl through the address space of your application, locate things that look like strings, and sniff out possible passwords. In theory, this could be done by:

  • a hack that breaks the JVM's execution model and looks at the raw memory,
  • attaching a Java debugger and trawling through the reachable objects,
  • using "/dev/mem" or similar to read process memory from the outside,
  • accessing the remains of a program's swap image on the hard drive, or
  • somehow causing it to core dump and reading the dump.

However, all but the first of these requires that the bad guy has already broken security on the system. And if the bad guy has done that there are other (probably simpler) ways to steal passwords from your program ... which the "no strings" approach won't prevent.

And if you are worried about a hack that exploits a Java security flaw to read raw memory, that flaw could probably used in other ways; e.g. to inject code to alter the way that the passwords are handled by the code.

So in summary, "no strings" is protecting against either really difficult hacks, or against cases where your security is already blown. IMO, it is not worth the effort ... unless you are required to implement military grade security.