QoTW #51 Would it be good secure programming practice to overwrite a “sensitive” variable before deleting it?
Jonathan recently asked this question about secure development practices, specifically, whether it makes a difference to your application’s security if you overwrite the values of sensitive variables as soon as you’re through with them. The rational is that if you don’t clear the variable values then there is a wider window of opportunity for a malicious party to be able to find and use the sensitive data by reading it out of RAM.
Gilles‘ answer explains that yes, this is important, and explains why. There are a number of reasons, and while an attacker reading the values out of RAM is a consideration, it isn’t even one of the more important ones.
Yes, it is good practice security-wise to overwrite data that is particularly sensitive when the data is no longer necessary, i.e. as part of an object destructor (either an explicit destructor provided by the language or an action that the program takes before deallocating the object). It is even good practice to overwrite data that isn’t in itself sensitive, for example to zero out pointer fields in a data structure that goes out of use, and also zero out pointers when the object they point to is freed even if you know you aren’t going to use that field anymore. One reason to do this is in case the data leaks through external factors such as an exposed core dump, a stolen hibernation image, a compromised server allowing a memory dump of running processes, etc. Physical attacks where an attacker extracts the RAM sticks and makes use of data remanence are rarely a concern except on laptop computers and perhaps mobile devices such as phones (where the bar is higher because the RAM is soldered), and even then mostly in targeted scenarios only. Remanence of overwritten values is not a concern: it would take very expensive hardware to probe inside a RAM chip to detect any lingering microscopic voltage difference that might be influenced by an overwritten value. If you’re worried about physical attacks on the RAM, a bigger concern would be to ensure that the data is ovewritten in RAM and not just in the CPU cache. But, again, that’s usually a very minor concern. The most important reason to overwrite stale data is as a defense against program bugs that cause uninitialized memory to be used, such as the infamous Heartbleed. This goes beyond sensitive data because the risk is not limited to a leak of the data: if there is a software bug that causes a pointer field to be dereferenced without having been initialized, the bug is both less prone to exploitation and easier to trace if the field contains all-bits-zero than if it potentially points to a valid but meaningless memory location.
Yes that is a good idea to overwrite then delete/release the value. Do not assume that all you have to do is “overwrite the data” or let it fall out of scope for the GC to handle, because each language interacts with the hardware differently. When securing a variable you might need to think about:
- encryption (in case of memory dumps or page caching)
- pinning in memory
- ability to mark as read-only (to prevent any further modifications)
- safe construction by NOT allowing a constant string to be passed in
- optimizing compilers (see note in linked article re: ZeroMemory macro)
- Use volatile
- Use pragmas to surround the code using that variable and disable optimisations.
- If possible, only assemble the secret in intermediate values rather than any named variables, so it only exists during calculations.
Storing a value that isn’t used again? Seems like something that would be optimized out, regardless of any benefit it might provide. Also, you may not actually overwrite the data in memory depending upon how the language itself works. For example, in a language using a garbage collector, it wouldn’t be removed immediately (and this is assuming you didn’t leave any other references hanging around). For example, in C#, I think the following doesn’t work.
string secret = "my secret data"; ...lots of work... string secret = "blahblahblah";
"my secret data"hangs around until garbage collected because it is immutable. That last line is actually creating a new string and having secret point to it. It does not speed up how fast the actual secret data is removed.
Several answers and comments also pointed out that when using a non-managed language like C or C++, when you can, you should also pin the memory in order to prevent it from being swapped to disk where sensitive values might remain indefinitely.
Like this question of the week? Interested in reading more detail, and other answers? See the question in full. Have questions of a security nature of your own? Security expert and want to help others? Come and join us at security.stackexchange.com.