I previously maintained a blog with the domain name securestring.net. Why “secure string”? Well, if you’ve ever encountered Static Application Security Testing (SAST) tools like Checkmarx, you may have come across warnings about storing credentials in string variables. Particularly in the context of .NET languages, the common recommendation was to use SecureStrings. Given my involvement in authentication-related projects, addressing issues flagged by SAST tools was a routine expectation for vulnerability resolution.
But SecureString is not the solution. First of all SecureString is available only in .NET Framework, not in the latest .NET versions since the first .NET core. The wiki page for the class SecureString Class (System.Security) | Microsoft Learn has an information block as below.
We recommend that you don’t use the
SecureStringclass for new development on .NET (Core) or when you migrate existing code to .NET (Core). For more information, see SecureString shouldn’t be used.
What is SecureString?
SecureString class attempts to avoid storing sensitive data in memory as plain text. String is immutable hence it’s value cannot be altered once it’s created. However, this does not provide security to store sensitive data. SecureString stores the data in encrypted format making it more resistant to memory inspection attacks. Unlike String, it’s mutable, i.e: you can change the value once it’s created (Yes, there is a method MakeReadOnly that can be called once the variable is populated with the data which kind of gives the perception of immutability).
Why SecureString should not be used?
Below content is from the link platform-compat/docs/DE0001.md at master · dotnet/platform-compat · GitHub which explains why we should not use SecureString
- The purpose of
SecureStringis to avoid having secrets stored in the process memory as plain text.- However, even on Windows,
SecureStringdoesn’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.
So, what is the solution?
Well, Microsoft seems to be suggested not to use credentials instead move to alternatives such as certificate-based authentication. Not practical always is it not?
Let’s take a look at what other frameworks do in this case? In Java, we don’t have a SecureString equivalent class. Instead, the recommendation is to use a character array to store passwords and zeroize it after use.
In Python, it’s suggested to use getPass. But getPass also does not store the problem of having the sensitive data stored in the memory. If the attacker can get access to the running python process, may be using some memory forensic tools, they can access the sensitive data.
Often, developers tend to address suggested vulnerabilities as indicated by the tools. However, security is a layered concept, and adopting a defense-in-depth strategy is crucial. It’s essential to go beyond merely fixing identified vulnerabilities. Consider avoiding the use of sensitive data in code whenever possible. Explore alternative authentication mechanisms that don’t rely on passwords (note that passwords are not the only form of sensitive data). Additionally, ensure the immediate disposal of variables, implement proper authorization for critical component access, and transition towards a zero-trust architecture, among other measures.
Conclusion
Why did I decide to acquire the domain SecureString.Net? During that period, I invested effort in educating both leaders and the security team about the importance of not blindly adhering to every recommendation provided by tools. It is crucial to comprehend the reasons behind the tool’s suggestions and then implement solutions based on a thoughtful rationale. I believed this philosophy would make for a great theme for my blog. However, I didn’t end up writing anything, and the domain eventually expired. This time around, I am determined not to face the same fate. I will be sharing engaging content related to this field. Stay tuned!
