4

long time lurker here finally having a question that I'm not seeing. I am writing a c# console application in dotnet core and trying to allow a user to input a password, and am concerned about security, particularly memory dumping.

Following: Password masking console application my understanding is that a password stored as a string variable could be exposed through a memory dump (reference).

SecureString would normally be the way to go here but doesn't seem to be supported in dotnet core.

I've tried to modify the code to use a char array, because my limited understanding is that it is not immutable so it will not all be stored in a single piece of memory. Honestly though security is not my forte, so my question is if this code below properly protects me from exposing the password through a memory dump?

        Console.WriteLine("Enter pass");
        char[] passwordArray = new char[256];
        int whileIndex = 0;

        while (true)
        {
            ConsoleKeyInfo key = Console.ReadKey(true);
            if (key.Key == ConsoleKey.Enter)
            {
                break;
            }
            else if (key.Key == ConsoleKey.Backspace)
            {
               if (whileIndex != 0) //so it doesn't explode if someone holds backspace
                {
                    whileIndex--;
                }
            }
            else
            {
                passwordArray[whileIndex] = key.KeyChar;
                whileIndex++;
            }
        }
        //Truncate array to length of password
        var endIndex = Array.IndexOf(passwordArray,'\0');
        char[] shortenedPasswordArray = new char[endIndex];
        Array.Copy(passwordArray, shortenedPasswordArray, endIndex);

        //Authentication code here

        //Wipe the characters when done
        foreach(var passChar in passwordArray)
        {
            passwordArray[passChar] = '\0';
        }

        foreach (var passChar in shortenedPasswordArray)
        {
            shortenedPasswordArray[passChar] = '\0';
        }
Community
  • 1
  • 1
Polymergraphy
  • 53
  • 1
  • 8
  • AFAIK an array would still have been allocated continuous memory space, – Vignesh.N Apr 13 '17 at 20:37
  • what is your threat model? Who doing what? – Neil McGuigan Apr 13 '17 at 21:25
  • @NeilMcGuigan wasn't sure how much that context would help. The purpose of this app is to run an LDAP query to pull down a list of AD objects, and I am requesting the user/pass to bind the connection. While I'd personally consider it lower risk than saving credentials/passing them between devices, it could potentially be performed by an IT Admin with valuable credentials, so wanted to do my due diligence here. – Polymergraphy Apr 13 '17 at 22:40
  • Who would be doing the attacking? Where are they? – Neil McGuigan Apr 13 '17 at 22:47
  • @NeilMcGuigan Maybe it'd be easier if I word this starting from the other direction. If this was a .NET Standard app I'd use SecureString here and call it a day, so we could re-phrase this as: how much additional risk is the code above introducing over using SecureString? To my knowledge the biggest difference is that SecureString encrypts in memory which makes it more protected against a memory dump. Am I off here? Is that risk unavoidable without recreating SecureString? – Polymergraphy Apr 14 '17 at 19:30

1 Answers1

2

Some comments: 1) First and foremost remember that security is not solved in one application. For somebody with full access to the machine there is (almost) nothing you can do to keep a password truly secure.

(Fun exercise: How would you authenticate a password without keeping the password in memory at all?)

2) SecureString only gives you more control over the lifespan of a password in memory by letting you determine when it goes away. A normal string may last a very long time in memory, even until the program exits, since it doesn't go away until garbage collection. SecureString lets you explictly wipe it, but it still exists in memory until then.

3) Using your own char array is a good idea, but I might have used a List because it allows a variable length, or maybe even a LinkedList because it spreads the characters out in memory. Shrug. Refer back to #1 and consider what kind of attacks you're protecting the password from.

Ray Fischer
  • 936
  • 7
  • 9
  • 2
    First paragraph is the clincher. Any vulnerability you can identify which requires the attacker to have unfettered physical access to the machine running the program is not a vulnerability you should be worried about as a programmer. That's not a code or data security problem; that's a physical security problem. So-called "white-box security", the idea that an attacker can watch everything the computer does and still cannot crack the security, is known to be hard and believed by some to be impossible. – KeithS Apr 19 '17 at 22:08
  • Appreciate this answer and comment. I realize the scenario I'm worried about may involve a computer so compromised that nothing could save it. Security is just a massive beast that I am very novice in, and mostly wanted to sanity check that I'm not doing some "password post-it stuck to the monitor" equivalent of coding here. Thank you. – Polymergraphy Apr 21 '17 at 19:17
  • I once worked for Microsoft. They have a policy the ONLY people on the security team are allowed to work on security because there are so many gotchas in computer security that the untrained are very likely to create disastrous backdoors. Don't feel bad if you don't know the field and it's very good to ask questions. – Ray Fischer Apr 21 '17 at 20:29