Storing sensitive information in memory

  MEDIUM  
Detection method   DAST         HEAPDUMP  

Description

Memory analysis can help developers to identify the sources of several problems that arise during runtime of an application on a device. But such analysis can also be used for gaining access to confidential data. When an application runs on a device, user data or application-specific data can be stored in RAM and not cleared properly after a user exits the system or the application. Since Android stores applications in memory (even after exit) until it is restored, confidential information can stay in memory for an indefinite period of time. A malicious person who finds or steals the device can connect a debugger and upload the memory dump.

Recommendations

Don't store confidential data (such as encryption keys) in RAM for more time than necessary. Clear all variables containing confidential information once they have been used. Avoid using constant objects (such as Android java.lang.String) when creating  cryptographic keys or passwords.

Store confidential information in primitive data arrays, such as byte arrays (byte []) and char arrays (char []). This helps to correctly clear confidential information from memory.
‎There are some methods of clearing memory information, one of them is to overwrite the contents by zeros.

Example: Java

byte[] secret = null;
try{
        //get or generate the secret, do work with it, make sure you make no local copies
} finally {
        if (null != secret) {
                Arrays.fill(secret, (byte) 0);
        }
}

Example: Kotlin

val secret: ByteArray? = null
try {
        //get or generate the secret, do work with it, make sure you make no local copies
} finally {
        if (null != secret) {
                Arrays.fill(secret, 0.toByte())
        }
}

‎This problem doesn't have an ideal solution. For example, you can perform additional calculations (such as XOR for data in a dummy buffer), but you won't know if the compiler decided to remove those operations. On the other hand, using data outside the compiler (for example, serializing the data in a temporary file) guarantees that the data will be overwritten, but, obviously, this affects performance.


‎Moreover, using Arrays.fill to overwrite data might be a bad idea because this method could be intercepted, which is often done by various instruments for analysis. Another problem in the example given above is that the contents are overwritten with zeros only. While ideal would be to overwrite objects containing confidential information with random data or with contents of other variables.

‎Example: Java

byte[] nonSecret = somePublicString.getBytes("ISO-8859-1");
byte[] secret = null;
try{
        //get or generate the secret, do work with it, make sure you make no local copies
} finally {
        if (null != secret) {
                for (int i = 0; i < secret.length; i++) {
                        secret[i] = nonSecret[i % nonSecret.length];
                }
                FileOutputStream out = new FileOutputStream("/dev/null");
                out.write(secret);
                out.flush();
                out.close();
        }
}

Example: Kotlin

val nonSecret: ByteArray = somePublicString.getBytes("ISO-8859-1")
val secret: ByteArray? = null
try {
        //get or generate the secret, do work with it, make sure you make no local copies
} finally {
        if (null != secret) {
                for (i in secret.indices) {
                        secret[i] = nonSecret[i % nonSecret.size]
                }
                val out = FileOutputStream("/dev/null")
                out.write(secret)
                out.flush()
                out.close()
        }
}

Links

  1. https://mobile-security.gitbook.io/mobile-security-testing-guide/android-testing-guide/0x05d-testing-data-storage
  2. https://cwe.mitre.org/data/definitions/316.html
  3. https://www.pentestpartners.com/security-blog/how-to-extract-sensitive-plaintext-data-from-android-memory/
  4. https://securitygrind.com/dumping-and-analyzing-android-application-memory/
  5. https://developer.android.com/studio/profile/memory-profiler