Use SecureString for credit card numbers
I've been looking into using the System.Security.SecureString class to hold credit card numbers开发者_运维知识库 in memory while they are being processed. Has anyone used the SecureString class for holding credit card numbers, or do most just use the normal System.String class?
From a PCI-DSS perspective, there is no requirement to protect card numbers stored only in memory.
PCI states only that card numbers persisted to disk, or transmitted across a network must be encrypted. This is a common sense approach to the issue. Using SecureString will ensure that the string is never cached to disk, but as you say - its troublesome to use. This post has some good suggestions though: https://stackoverflow.com/questions/122784/hidden-net-base-class-library-classes#123141
In theory, protecting memory sounds like it would add strength, but in truth if a bad guy has access to the RAM, then its pretty much game over anyway.
The previously-accepted answer from 2010 may have been correct at the time, but please be aware of PCI DSS 3.0 section 6.5, which states:
Train developers in secure coding techniques, including how to avoid common coding vulnerabilities, and understanding how sensitive data is handled in memory.
It's ultimately about adhering to industry best-practices.
Given the high-profile breaches in recent years, where sensitive data (including credit card information) is captured by malware, attackers, etc. scraping memory, more focus is being put on keeping sensitive information secure, even in memory.
Use SecureString where possible.
Where it isn't possible, just understand what you're up against. Since strings are immutable and garbage collection can't always be relied on, you just have to work with what you've got. One method I've read about is to make the string into a BSTR, copy it into a pinned string, then both the BSTR and pinned string are zeroed after use. It feels a bit 'hacky', but it's better than doing nothing at all.
If doing the credit card number capture purely within a winform app, keeping the card number secure in memory is quite doable.
With an ASP.NET web app, though, I'm not sure... I haven't tried it, but the general consensus on SO seems like it's not worth it. Additionally, MSDN mentions ASP.NET apps specifically, by saying:
Use of the SecureString class is less appropriate in ASP.NET applications. It is unlikely that you can extract data from a Web page that contains sensitive data (such as a credit card number) and place it inside a SecureString without it having already passed through intermediate System. String objects
You're probably done with your project, but hopefully this will assist others.
I use SecureString for other stuff (not credit cards), if it's going to be cached in memory for an extended time.
The problem I keep encountering is that you still have to marshal it to a normal String in order to actually use it for anything, so it's really limited in its usefulness.
I've created a couple of extension methods to ease working with them a little bit:
public static unsafe SecureString Secure(this string source)
{
if (source == null)
return null;
if (source.Length == 0)
return new SecureString();
fixed (char* pChars = source.ToCharArray())
{
SecureString secured = new SecureString(pChars, source.Length);
return secured;
}
}
public static string Unsecure(this SecureString source)
{
if (source == null)
return null;
IntPtr bstr = Marshal.SecureStringToBSTR(source);
try
{
return Marshal.PtrToStringUni(bstr);
}
finally
{
Marshal.ZeroFreeBSTR(bstr);
}
}
Don't use securestring. PG is deprecating it. Watch the video and they outline a myriad of security problems with it. https://github.com/dotnet/apireviews/tree/master/2015-07-14-securestring .
精彩评论