Search code examples
c#.netwpfsecuritypasswordbox

How secure is the WPF PasswordBox, really?


I've already asked a couple of questions around the PasswordBox recently, but at the heart of my issue, I need an extremely secure way of getting very sensitive information inputted into my .Net application.

Out of the box, the WPF PasswordBox is the go to control for getting passwords, or other sensitive information. For the sake of security, it provides a SecureString object through the SecurePassword property which is, in my case, secure enough for my needs. However, there is one major flaw that I see with this control-- it has a Password property which is the user-entered content in an insecure .Net string.

I would like to assume that if I never access the Password property within my application, an insecure version of my sensitive information will never be generated and have to be garbage collected. That fine. However, since the point of the secured form of the string is to keep the value secure from a snooping process (I assume) that can read the .Net memory, could the same snooping malicious codes simply look for a PasswordBox that is hanging around in memory and find some way to access the Password field, making the use of the SecureString value essentially useless?

I will admit, I have no clue how these exploits are executed. However, if the problem is that some application might be sniffing your variables in the .Net memory manager/garbage collector, it would seem plausible to me that all they'd have to do is access the PasswordBox control object, rather than a string object in memory and simply access the Password property. What might I be missing in this puzzle? How is the PasswordBox even secure if it contains a Password property in clear text?


Solution

  • PasswordBox.Password property creates .NET string from SecurePassword property, it does not store it as string internally. The whole point of using SecureString is to reduce amount of time sensetive data is present in memory, and reduce number of copies of that sensetive data. You can read more about SecureString in documentation.

    SecureString is encrypted (if possible, and usually it is), so if someone can just read raw memory (such as someone stealing your memory dump) - he will not be able to read your password from it. If your application is so compromised that attacker can inject his own dll into your process and run arbitrary code there - then you have bigger problems anyway (and still there is high chance that password will not be present in memory already).

    That said, you can still follow some reasonable guidelines when using PasswordBox and SecureStrings in general.

    1. Always dispose result of PasswordBox.SecurePassword if you ever need to access it:

      using (var pwd = myBox.SecurePassword) {
          // do stuff
      }
      

    This might look strange (disposing something returned by property), but it should be done, because this property returns a copy of SecureString and should have been a method instead, but for some reason is property.

    1. Access Password property as rare as possible, preferrably only once when you really need it. You don't want copies of password to stay in memory more and longer than needed.

    2. Always call yourBox.Clear() when you are done. This will set password to empty string and clear interal SecureString memory.