I have recently been doing a security code review for my company and using a tool called Fortify360. It will identify many issues with the code and describe the problems. An interesting issue it has raised that I have not found any other info on is the following:
"Sensitive data (such as passwords) stored in memory can be leaked if it is stored in a managed String object. String objects are not pinned, so the garbage collector can relocate these objects at will and leave several copies in memory. These objects are not encrypted by default, so anyone that can read the process' memory will be able to see the contents. Furthermore, if the process' memory gets swapped out to disk, the unencrypted contents of the string will be written to a swap file. Lastly, since String objects are immutable, removing the value of a String from memory can only be done by the CLR garbage collector. The garbage collector is not required to run unless the CLR is low on memory, so there is no guarantee as to when garbage collection will take place. In the event of an application crash, a memory dump of the application might reveal sensitive data."
All of this I understand to make good sense and in my research of the issue is pretty standard.
The question is: how do I solve the issue? Suppose the class or classes that are in question cannot inherit from iDisposable(very large app, and the class is needed long after the string in question). Is there an alternate way of manual memory management to dispose of a specific string without calling the garbage collector, GC.Collect()??
Appreciate the help in advance.
Alex
If you want to avoid this you need to use System.SecureString, which is IDisposable
, to hold sensitive data, holding onto this only for the minimum possible time required.
It's kind of ironic that the MSDN sample code does not Dispose
the instance, either explicitly or with using
encapsulation.
Honestly, solving this "problem" will be more trouble than it's worth.
Keeping user-submitted passwords around in strings cannot be prevented when using technologies like ASP.NET, unless you are going to encrypt the strings client-side before sending them, since ASP.NET will store them as strings in form collections, etc.
And if you did go the JS-encryption route, note that any potential attacker would also be able to decrypt the strings he recovered from your application.
However, if someone has broken into the web server, chances are good that he can compromise the entire database. And that's a much worse issue than gathering a few passwords from the heap of the web server...
Now, if this is not an ASP.NET application, and you have complete control over how passwords are processed in code, you could take a look at SecureString. But you may still find that the minimal benefits outweigh the increased code complexity. It really depends on how bad a password leak would be, and how vulnerable your machines are to being compromised in the first place. If you are not worried that some remote attacker will be able to debug your processes and take memory snapshots, this is really a non-issue.
In summary: If an attacker has the power to extract these strings from memory or swap, he also has the power to do things that are far worse.