1

This question is directed at the .Net framework, but would hopefully be answered to encompass many languages & frameworks.

Let's assume I have a two methods, one which actually decypts data and one which takes the decypted data and returns it to the user:

private string Decypt_Data(string encryptedText, string EncryptionKey) {

    string plainText = "";
    using(SomeEncryptionClass  myObject = new SomeEncryptionClass()) {

        myObject.Key = EncryptionKey;  //lets not worry about how we create or store these
        myObject.IV = GetIV();

        plainText = myObject.DecryptText(encryptedText);  

    }

    return plainText;  //REFERENCE 1

}

//specifically this is called from a controller after a POST
private ActionResult Read_Encrypted_Value()
{

    string encryptedEncryptionKey = GetDataFromDatabase("keyfield");
    string encryptionKey = Decypt_Data(encryptedEncryptionKey, GetKeyFromSomeWhereThisIsUnImportant());

    //decrypt data with plainText (ie. plainText is a key.. but this isnt important to the question)
    syromg encryptedData = GetDataFromDatabase("datafield");

    return View(Decypt_Data(encryptedData, encryptionKey));   //RFERENCE 2

}   

Looking at the Decrypt_Data method, encrypted text is passed in and decrypted then the plain text is returned.

The question is... how secure is the value stored in "plainText" (at REFERENCE 1)?

The variable plainText only lasts for the scope of the method... but what then? Does that value remain in memory until the Garbage Collector deals with it? Does it get NULLed or something? Should I do something like at REFERENCE 2, where I do the calculate and return the value together? Should I pass strings in as references, so that the variable returning the value doesnt need to be instantiated?

If the value remains in memory, is it not vulnerable? Can an attacker not read memory and steal the value? (I'm working on the princaple that this value is used to decrypt some other data... so the attacker having direct access to the database does not give him all the data).

The Answer

Thanks a lot everyone for your answers, I found this article: http://web.archive.org/web/20090928112609/http://dotnet.org.za/markn/archive/2008/10/04/handling-passwords.aspx in one of the links from user10008's answer. It pretty much covers everything you need to know + complete code listing.

  • The attacker can read memory and steal the value if the attacker has access to the memory. If the attacker has that much access, there's very little you can do. Regardless of what you do with this code, there's going to be at minimum another copy that's a part of the HttpResponse body that will be built after the view is returned. Even if youcould purge it from memory here, it will still be in memory there, until the GC cleans it up. – Xander Sep 11 '14 at 13:23
0

You are right, this is a common problem for code handling sensitive data. In the .Net managed environment, even if you zeroed out your string, you would still run into problems, due to movement of the string as a result of garbage collection. The garbage collector wants to defragment the heap and therefore can move your string around. Moving of course doesn't zero the data, its rather copying. Therefore you should tell the GC to "pin" the particular string to prevent its movement. See above link on how to do that.

And no, the data doesn't get zeroed, it is possible that when your program exits (or before when it frees memory), this memory becomes available to possibly hostile other processes.

SecureString may store the data in a safe way, but you still need to interface it with the outside world. This question covers that topic.

  • That SecureString needs to be kept as a SecureString end-to-end within the system, otherwise you hit the same problem as soon as it gets marshaled into a regular string. The provided answer is wrong, but @Doug's answer does a way better job to protect the string. – Steve Sep 11 '14 at 19:49
  • I've marked this one as correct, as the links lead to this article: web.archive.org/web/20090928112609/http://dotnet.org.za/markn/… which pretty much covered everything I need to know. – binks Sep 11 '14 at 19:55
  • @Steve Doug does basically the same as the accepted answer of the question. Its really just a class wrapped around the stuff the article covered. I guess he's just copied it into a class and added some comments. – user10008 Sep 12 '14 at 0:09
  • @user10008 you're right, I missed the link. My concern was how he was pinning the string in the first place, which he didn't elaborate on, whereas Doug's answer explicitly showed it. – Steve Sep 12 '14 at 16:26
0

This really is dependent on the language, if it's compiled then what compiler was used.

The question is... how secure is the value stored in "plainText" (at REFERENCE 1)?

Without using a special secure class this variable will reside in memory until it is overwritten. Not all languages provide a "secure class" for data. Freeing memory does not always imply zeroing memory out. It only invalidates the pointer with the memory manager. Some garbage collectors might zero out the memory automatically for you, C of course will not zero anything out when you free memory.

If the value remains in memory, is it not vulnerable?

It is still vulnerable to memory reads. If that portion of memory is not overwritten and an attacker reads that memory, the plaintext will be there. This also applies even if the program has been closed.

The best way to mitigate this problem in general is to limit the scope of the sensitive data, and overwrite the memory yourself when you're done using it. You can zero it out, you can overwrite it with random data, whatever you want. This way when the memory is viewed outside of its scope there is no sensitive data.

In .NET the garbage collector will overwrite the memory of the dead objects for you when the variables leave scope. This 2-page article explains .NET Garbage Collection

Once the dead objects have been identified, the garbage collector starts a new procedure. This moves the live objects within the heap, overwriting the memory used by the dead objects to remove dead items and make the heap contiguous again.

I would still overwrite the data yourself to be safe (if possible, depends on the language). But I'm also a bit paranoid.

  • 1
    You can't overwrite a string in .Net. They're immutable, so it will live in the heap until it's GC'ed. – Xander Sep 11 '14 at 13:24
  • @Xander That's unfortunate, this is why I stick to low level programming :) – RoraΖ Sep 11 '14 at 13:26
  • <Shrug /> Yes and no. Yes, it is unfortunate when you want to explicitly null out memory I agree, but on the other hand, it eliminates entire classes of security vulnerabilities. Something like Heartbleed, for instance, would have been impossible in a managed language. – Xander Sep 11 '14 at 13:30
  • @Xander That's true. Everything's got there pluses and minuses, strikes and gutters. – RoraΖ Sep 11 '14 at 13:34
  • 1
    @user10008 If you null a pointer it just makes that reference invalid. It does not change the data residing in memory. – RoraΖ Sep 11 '14 at 14:42
-1

In .Net you can use secure string to have some level of protection against memory reading like that : http://msdn.microsoft.com/en-us/library/system.security.securestring(v=vs.110).aspx

  • Sort of. Yes, SecureString itself can protect the data, but as @user10008 mentioned in his answer, you still must get the data into and out of the SecureString in order to use it, and it's vulnerable there. SecureString's use cases are pretty limited. It's not a general string replacement. – Xander Sep 11 '14 at 13:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.