Tuesday, August 19, 2014

Why not to store sensitive data like password in String objects.


The String class in java in immutable which means that once a String object is created, it can't be removed or modified from the Heap. It can only be removed in the next garbage collector cycle if the reference was made null.

What this means is that the object is available on the heap unless it is garbage collected. That means the sensitive information in the String object will be exposed to anyone having the access to the heap dump.

Lets create some String objects, take a heap dump and see the sensitive data.
The below code iterates the for loop 100 times and adds sensitive strings in the String array.

 
package heap;
public class WhyNotToSaveSenstiveDataInString {
 public static void main(String[] args) {
  String password = "MyConfidentialPassword";
  String passArr [] = new String [100];
  for (int i = 0; i < passArr.length; i++) {
   passArr[i] = password.concat(String.valueOf(i));
  }
  while(true){}
 }
}


Notice, that we have kept the application up by putting a infinite while loop. We will use the visualvm tool to take the heap dump.
Go to java bin directory and start jvisualvm.exe.






Once started, we can see our application in the sidebar. Right click it, and select Heap Dump. We can see heap dump as below. We can see the sensitive information highlighted in yellow. This information is exposed to anyone having the access to the heap dump and hence can be a compromise with the security.
One can also use OQL (object query language) to dig in more precise information.



The issue with String is that once a sensitive information is stored in it,it can't be changed programmatically. One becomes completely dependent on the next garbage collection cycle which can reclaim it only if the reference was made null.

The better option is to use a char [] to store sensitive data. Because as soon as we have used the data, we can reset the char[] with junk characters. This reduces the dependence of the security on garbage collector.

 
char[] charPassword = new char[]{'C','o','n','f','i','d','e', 'n','t','i','a', 'l'};
// Do some computation

//Fill the char [] with junk data so that the senstive information is erased
Arrays.fill(charPassword, '0');

for (int i = 0; i < charPassword.length; i++)
 System.out.print(charPassword[i]);

Output : 000000000000

Also, printing the char[] object to the console/log wont print the value of the sensitive data.

 
String strPassword = "Confidential";
char[] charPassword = new char[]{'C','o','n','f','e','d','e', 'n','t','i','a', 'l'};
System.out.println("String password: " + strPassword);
System.out.println("Character password: " + charPassword);

String password: Confidential
Character password: [C@15db9742

One can be even more careful and use the confidential data in encrypted form rather than using clear text.









No comments:

Post a Comment