8

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

Alex McKay
  • 103
  • 1
  • 2
  • 5

2 Answers2

9

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.

Steve Townsend
  • 53,498
  • 9
  • 91
  • 140
6

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.

cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • True, but reducing attack surface may be worthwhile. OP stated that sensitive string lifetime is << than class lifetime. – Steve Townsend Nov 15 '10 at 21:09
  • Of course. But the risk and effort required to fix should be properly evaluated, instead of relying on diagnostic tools that produce "scary" results. – cdhowie Nov 15 '10 at 21:16
  • 1
    +1. If a bad guy is at a point where he has access to the memory then its game over. He can drop in a screen scraper, a keylogger, trojan. At that point, someone scanning the memory is the least of your worries. – PaulG Nov 16 '10 at 09:45
  • The application is not ASP.NET or web based, and of financial nature so trying to reduce the attack surface in every way helps. – Alex McKay Nov 17 '10 at 04:25
  • @Alex, I would suspect you haven't yet looked into how difficult using SecureString will be, and how little extra protection it provides. See http://www.csharp411.com/securestring-safe-from-forensics-but-not-surveillance/ for example. Getting the value back from a secure string immediately invalidates the security. – PaulG Nov 18 '10 at 10:15
  • I understand why SecureString can't export its value as a String. Would there have been any difficulty with providing a Chars() indexer to query individual characters by value? – supercat Feb 19 '11 at 00:00