7

This is a memory data security question.
Does java garbage collection securely wipe out garbage data?

Apparently after a chunk of data is garbage-collected, I cannot retrieve it anymore, but can a hacker still memory-dump to retrieve the data?

Andrew Lygin
  • 6,077
  • 1
  • 32
  • 37
Liwen Zhao
  • 545
  • 5
  • 9
  • Related: http://stackoverflow.com/questions/8881291/why-is-char-preferred-over-string-for-passwords-in-java – shmosel Jul 29 '16 at 20:40
  • Memory security is hard to do. Also when someone breaks into your phone to scan memory for data, they can pretty much get most of the secure information from your phone. Effort can be better spent in securing data in storage and in transit. – david m lee Aug 04 '16 at 02:49
  • It's the HIPAA Compliance that I'm worried about. Not sure whether HIPAA Compliance requires memory encryption or not. – Liwen Zhao Aug 04 '16 at 16:17

3 Answers3

6

As other users already mentioned here, JVMs don't clean memory securely after garbage collection because it would affect performance badly. That's why many programs (especially security libraries) use mutable structures instead of immutable (char arrays instead of strings etc) and clean data themselves when they are no more needed.

Unfortunately, even such approach doesn't always work. Let's look at this scenario:

  1. You create a char array with a password.
  2. JVM performs a garbage collection and moves your char array to another place in the memory, leaving the memory previously occupied by it intact, just marking it as a free block. So, we now have a 'dirty copy' of your password.
  3. You are done working with your password and explicitly zero all the characters in your char array thinking that everything is safe now.
  4. An attacker makes a dump of your memory and finds your password in the memory where it was placed the first time, before step 2.

I can think of only one possible solution for this problem:

  1. Use G1 garbage collector.
  2. Make your sensitive data a single block (array of primitive values) that is large enough to occupy more than half of the region size, used by G1 (by default, this size depends on the maximum heap size, but you can also specify it manually). That would force the collector to treat your data as so called 'humongous object'. Such objects are not moved in memory by G1 GC.
  3. In such case when you erase some data in your block manually, you can be sure that no other 'dirty copies' of the same data exist somewhere in the heap.

Another solution would be to use off-heap data that you can handle manually as you like, but that wouldn't be pure Java.

Andrew Lygin
  • 6,077
  • 1
  • 32
  • 37
  • In Go you're able to use syscalls to request memory directly from the kernel (mmap/virtualalloc etc) using pure Go. Not sure if something similar would be possible in Java. – Awn May 28 '17 at 15:27
2

This depends on the JVM implementation and possibly options within it but I would assume that it won't clear the data. Garbage collection needs only track which areas are available. Setting all of that data to 0 or something else is a lot of unecessary writes. It's for this reason you will often see APIs use a char array for passwords instead of Strings.

JimmyJames
  • 1,356
  • 1
  • 12
  • 24
  • It's worth mentioning that char arrays only decrease the probability of an attack success, but do not guarantee its total elimination. – Andrew Lygin Jul 29 '16 at 18:37
  • @AndrewLygin Right. I also didn't mention that you need to clear the array yourself. There's nothing inherent about the array that prevents reading it's contents from a memory dump. – JimmyJames Jul 29 '16 at 18:41
  • Unfortunately, things are a bit more complicated here and even clearing the data manually will not always allow to get rid of them completely. See my answer for details. – Andrew Lygin Jul 29 '16 at 19:02
  • I didn't mean to imply that this was a safe method but the reason a char array is used is in order to attempt to clear it. – JimmyJames Jul 29 '16 at 19:09
  • Sure, then you're right. I just saw many times that people suggest usage of mutable structures and cleaning them manually as an absolutely safe approach. Just wanted to make it clear that it's not. – Andrew Lygin Jul 29 '16 at 19:12
  • @AndrewLygin Absolutely a helpful comment. Your answer has really good detail on this issue. – JimmyJames Jul 29 '16 at 19:15
0

Specifically Oracle JVM won't clear the space, it only copies data between Eden and Survivor spaces, objects that are no longer used just stay there as a garbage that will be overwritten eventually. Similar thing happens in the OldGen, some places are marked as used, and when object becomes eligible for garbage collection, the place it occupied is marked as not used. It will also be overwritten eventaully, given enough application time.

Krzysztof Krasoń
  • 26,515
  • 16
  • 89
  • 115
  • Is Oracle JVM a typical Java VM? I'm more concerned with Android app data security. – Liwen Zhao Aug 04 '16 at 02:28
  • @LiwenZhao Android (or rather Dalvik/ART) is not a JVM so you can't apply anything from JVMs to it. Please annotate your question with `android`. Oracle is THE JVM, reference implementation. – Krzysztof Krasoń Aug 04 '16 at 06:26