In Java the old way of storing a secret, such as a password, was to use char[]
as you could overwrite its data when you were done with it. However this has since been shown to be insecure as the garbage collector will copy things around as it reorganizes the heap. On certain architectures it's possible that a page will be freed and the secret will remain when some other program allocates that same page.
This is horribly ugly, but what if the secret were stored on the stack of a Thread's run
method? Care would still need to be taken to terminate the thread gracefully, so that it could zero out its data, but this problem was present in the old way as well.
One major problem I see straight away is that I can't think of a safe way to get data in and out of the container. You could minimize the likelihood of a leaked secret by using streams with very small internal buffers, but in the end you wind up with the same problem as char[]
. [Edit: Would a single private static byte
member and a flag work? Although that would limit you to one secret per ClassLoader. This adds more ugliness, but it might be easy enough to hide behind a well-written interface.]
So I have a bunch of questions, really.
Is the stack any more secure from these types of attacks than the heap? Are there any pure Java mechanisms to perform a stack-to-stack copy between two different stack frames in a manner that would be useful to this problem? If not, would the JVM even support this type of operation in bytecode?
[Edit: Before people worry too much, this is more of a thought experiment than anything else. I have absolutely no intention of 'testing in production' or using it in any current project. I realize that what I'm talking about is really ugly, probably horribly bulky, and works against the entire JVM structure. I'm just interested in whether it's possible, whether it actually accomplishes my goals, and what kinds of heroics it would take to make it happen.]
I would use a direct ByteBuffer. The memory this uses is not copied around and is only in one place for the life of the ByteBuffer. BTW don't use clear() as this just resets the position. You can overwrite it with
bb.clear();
while(bb.remaining() >= 8) bb.putLong(0);
while(bb.remaining() > 0) bb.put((byte) 0);
Is the stack any more secure from these types of attacks than the heap?
I wouldn't think so.
Are there any pure Java mechanisms to perform a stack-to-stack copy between two different stack frames in a manner that would be useful to this problem?
You could store the secret as one or two long
s.
If not, would the JVM even support this type of operation in bytecode?
The byte code is designed to support Java and does very little more than what you can do in Java.
I'm just interested in whether it's possible, whether it actually accomplishes my goals, and what kinds of heroics it would take to make it happen
Use a direct ByteBuffer as I have suggested. ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With