27

I am creating a .NET core webapp in C# that takes in a user password and hashes it to be stored on a server. I'm using Rfc2898DeriveBytes along with a randomly generated salt. I've read, however, that I should avoid using strings in the entire process since strings cannot be removed from memory. I know that .NET core has a PasswordBox that keeps the password as a SecureString, but SecureStrings cannot be converted to a byte array to be passed to Rfc2898DeriveBytes's constructor without a great deal of shenanigans.

Since the webapp is only going to run on my server, can I just convert the SecureString back to a string as soon as it has been passed into my webapp? If an attacker manages to access the server's RAM to search for an undeleted string, there's probably very little I can do to protect anything to begin with.

If I should still go through with using SecureStrings, what are the best practices for hashing it to be stored?

34

Using SecureString correctly is difficult, and protects against a threat surface that is unlikely for most use cases. As you say, if an attacker can read your memory, you have other problems. I would advise to use normal strings instead of SecureString, unless you are worried by attackers carrying liquid nitrogen with physical access to your server.

If you really want to use SecureStrings, you should P/Invoke the Windows crypto API so that you have control over memory. I have an example in my blog post Comparing secure strings in .NET.

  • 8
    No liquid nitrogen needed: there software (Heartbleed) vulnerabilities that allow reading parts of RAM, and hardware vulnerabilities like Spectre can be exploited in a cloud environment. But I agree that it's rather unlikely and not something most web apps should be concerned with. – aland Aug 20 at 16:10
  • What's the thing about liquid nitrogen? – IEatBagels Aug 22 at 15:52
  • In a cold boot attack, memory can be cooled with liquid nitrogen so that data persists while moving the DRAM modules to another computer to read the data. – Sjoerd Aug 22 at 19:18
49

The .NET Core team specifically recommends against using SecureString for new development. See the SecureString documentation:

We don't recommend that you use the SecureString class for new development. For more information, see SecureString shouldn't be used on GitHub.

as well as the team's reasoning on GitHub:

Motivation

  • The purpose of SecureString is to avoid having secrets stored in the process memory as plain text.
  • However, even on Windows, SecureString doesn't exist as an OS concept.
    • It just makes the window getting the plain text shorter; it doesn't fully prevent it as .NET still has to convert the string to a plain text representation.
    • The benefit is that the plain text representation doesn't hang around as an instance of System.String -- the lifetime of the native buffer is shorter.
  • The contents of the array is unencrypted except on .NET Framework.
    • In .NET Framework, the contents of the internal char array is encrypted. .NET doesn't support encryption in all environments, either due to missing APIs or key management issues.
  • 2
    Very interesting, great first answer! It should be noted that process memory in general is only really an attack surface if an attacker is able to get access to it - something that is generally not part of the threat model of a web application, unless on a shared host. – MechMK1 Aug 19 at 11:11
  • @MechMK1 That is mentioned in the other answer already, I just wanted to add the official recommendation, too. – Vivelin Aug 19 at 11:18
  • The quoted part says nothing about recommending against using SecureString. Could you please quote (or bold) the relevant parts. – Andrew Savinykh Aug 19 at 19:33
  • 2
    @AndrewSavinykh It's in the first link and doesn't really say more than that they don't recommend it for new development and contains a link to the quoted part. – Vivelin Aug 20 at 4:45
  • 1
    Maybe because you can ask the debugger (WinDbg + SOS) or profiler for objects of type SecureString, which makes password discovery even easier than using regular strings. With some IL injection, it's a one-liner to decode the password. – Thomas Weller Aug 20 at 21:18

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.