3

I am implementing SecureString in a project. After reading up on it and seeing lots of examples basically doing the same thing, I keep thinking that something is wrong.

Take for example the following code:

public static string ToUnsecureString(this SecureString secureString)
{
    if(secureString == null)
        throw new ArgumentNullException("secureString");

    IntPtr unmanagedString = IntPtr.Zero;
    try
    {
        unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(secureString);
        return Marshal.PtrToStringUni(unmanagedString);
    }
    finally
    {
        Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString);
    }
}

It's great to have the data secured, but what's really the point when in the end it just gets set to a standard string again?

I know you can just store the password in a char[] and then zero it out after creating the SecureString, but what am I supposed to do when retrieving the string? I did not see a way to retrieve it as a char[] and wouldn't just calling .ToCharArray() still leave the string that Marshal.PtrToStringUni(...) returned in memory?

Am I just missing something extremely fundamental? Thanks.

TyCobb
  • 8,909
  • 1
  • 33
  • 53
  • 4
    What is the point of putting money in the bank when you're just going to have to take it out again? The point is that it is secure while its there. This question is strange to me; the question is basically "I took something out of the secure box it was in and now its unsecured, so why did I have it in a box in the first place?" I don't know; you tell me. Why did you put it in a secure box if you were planning on taking it out? – Eric Lippert Sep 03 '13 at 01:21
  • @EricLippert I understand where you are coming from and I'll use your example as my reasoning for asking (which may be flawed). Yes, once the item is out of secure box, it is unsecure. However, you can always put the item back in the box. With the strings being immutable, aren't they stored in memory for quite awhile even after the method returns? If I am mistaken, please let me know and I'll go ahead and delete this question. Thanks – TyCobb Sep 03 '13 at 02:03
  • The point is that you'll never take it out into a managed string at all. Either consume it directly in low level code, or copy the data to a *mutable* array which you wipe directly after use (but even that's tricky thanks to the GC moving objects around in memory) – CodesInChaos Sep 04 '13 at 08:49
  • Another important point about `SecureString` is that it's only about keeping the string out of crashdumps, the swapfile etc. It's not about protecting the string from the user or hostile processes. – CodesInChaos Sep 04 '13 at 08:54
  • 1
    "did not see a way to retrieve it as a char[]" What about [`Marshal.Copy`](http://msdn.microsoft.com/en-us/library/ms146632.aspx)? – CodesInChaos Sep 04 '13 at 09:03
  • @CodesInChaos Special thanks for showing me `Marshal.Copy`. Had I known about that, this question would have never existed. Just trying to handle sensitive data like passwords and social security numbers as best as I can. – TyCobb Sep 05 '13 at 03:58

1 Answers1

1

You're right -- using the contents of a SecureString in managed code is pretty silly. However, for P/Invoke APIs such as the Windows Credential API, it's just the thing for keeping your password away from prying eyes.

Another possibility is to call Marshal.SecureStringToBSTR() and do all your processing in unmanaged code, you can still maintain some semblance of security.

Eric Lloyd
  • 509
  • 8
  • 19
  • So doing it in an `unsafe` context will help free up the actual string in memory? Is there any issue with doing this on a web application? – TyCobb Sep 03 '13 at 17:51
  • I mis-spoke. That's what I get for answering in the middle of the night. Then, of course, there's this little gem I didn't see yesterday: http://stackoverflow.com/a/11459012/136062 – Eric Lloyd Sep 04 '13 at 08:27
  • Excellent. Thanks a lot for that link. If you want to update your answer, I'll accept it. It suited my wants of not having the sensitive data in an immutable string. – TyCobb Sep 05 '13 at 03:56