#980 – Getting Data Out of a SecureString

Confidential data stored in an instance of the SecureString type is stored in memory on the unmanaged heap, in an encrypted form.

If you need to work with the data in an unencrypted form, you can read the data out of the SecureString into an unmanaged string (BSTR).  Once you are finished working with the confidential string data, you should zero out the memory where it was stored.

Below is an example of using the Marshal.SecureStringToBSTR method to work with string data stored in a SecureString.

        private void DoSomethingWithSecureStringData(SecureString secStr)
        {
            // using System.Runtime.InteropServices
            IntPtr unmStr = Marshal.SecureStringToBSTR(secStr);

            try
            {
                // Do something with unmanaged confidential string here.
            }
            finally
            {
                Marshal.ZeroFreeBSTR(unmStr);
            }
        }

When you call the SecureStringToBSTR method, the SecureString object decrypts its data and copies it to a new BSTR, before re-encrypting it.

 

Advertisements

#979 – Store Confidential Data Only Within SecureString Instances

You can use the SecureString class to securely store confidential text-based data.

The most important guideline, for security purposes, when using the SecureString class is:

Never store confidential data in a managed object (other than an instance of a SecureString)

If you transfer data from a SecureString into some managed object (e.g. a string or a byte array), the data will be less secure, due to the security issues with storing data in managed objects.

If you must work with confidential data in memory within your application, the proper procedure is to extract and decrypt the string data, but to store it in an unmanaged data structure (e.g. a BSTR).  The data will be vulnerable while in memory within the unmanaged object, but you can then explicitly delete the data when done working with it, limiting the amount of time during which the data is vulnerable.

#978 – Use a SecureString Object to Store Confidential Text Data

There can be security issues with storing confidential data in the System.String type, given that the string exists in plaintext in memory and you can’t explicitly control the amount of time during the string is present in memory.

The SecureString class provides a more secure way of storing confidential string data in memory.  SecureString is more secure than the String data type because:

  • It stores the string data in memory in an encrypted form
  • The encrypted data is stored in unmanaged memory and therefore not visible to the garbage collector
  • It allows appending, inserting or removing characters, but re-encrypts the data after modifying it
  • It is mutable, avoiding the need to create extra copies when modifying the secure string
  • It zeros out the contents of the string when the SecureString object is disposed (or finalized)

#977 – Security Issues with Managed Strings

Confidential data stored in strings is vulnerable to attack during the time period that the string is stored in memory.

String data stored in managed strings in .NET is less secure than data stored in unmanaged strings.  Plaintext (non-encrypted) string data in managed strings has a longer period of time during which it is stored in memory.

Because managed strings exist on the garbage collected heap, you can’t explicitly destroy them.  The data will remain in memory until after the garbage collector has released the memory and it has been overwritten by some other object.

Since strings are immutable, you can’t overwrite the string data in a managed string object.  Writing new data results in a new instance being created.  The Garbage Collector may also create extra copies when it compacts memory.  The string data is less secure, due to the likelihood of there being multiple copies and its longer lifetime.

#976 – Security Issues when Storing Confidential Data in Strings

Applications often have periods of time during which they need to work with confidential string data, e.g. credit card numbers or passwords.  Whenever you store this confidential string data within memory, the data is vulnerable to being read by any other process on your machine that can read your application’s memory.

Since memory can be swapped out to disk, confidential data stored in memory can also end up being stored on disk, making the data vulnerable for a longer period of time.

No matter what language your application is written in, these vulnerabilities exist whenever you store confidential data within memory as a plaintext (non-encrypted) string.

When writing code that deals with confidential data, you’ll eventually need to work with that data in memory.  To maximize security, you want to reduce the amount of time during which the plaintext version of data is stored in memory.