44850

Is there any benefit to using SecureString in ASP.NET?

Question:

If I understand correctly, this is for keeping plain text out of memory, so that the app is secure against esoteric attacks on memory, the garbage heap, or memory paged to disk. The SecureString is fed unmanaged bytes and consumed one unmanaged byte at at time--then the string is erased from memory. (Correct me if I way off!)

In ASP.NET, the secret is collected in a webform, which post back in HTTPS. But then the Request object turns all the request values from the form into name value pairs and puts them in a collection, e.g. Request["TxtPassword"]-- so even before I can get the string, it's already been written insecurely to memory. Worse, if I was using a control, then the unsecure representation will have more managed strings in the property of the TextBox.

To do anything with this SecureString I need an API that takes unmanaged strings--so it seems I can't use the secure string for a stored proc parameter or much else.

Am I doing this wrong or is it a fool's errand to try to use SecureString and not leak copies of the unsecured string into managed memory?

Switching to OAuth or Windows auth isn't an option.

Answer1:

As you correctly deduced, and others already mentioned, it makes little sense to use <a href="http://msdn.microsoft.com/en-us/library/system.security.securestring.aspx" rel="nofollow">SecureString</a> to store security-sensitive data that comes from an ASP.NET form, because that data is already present in memory in plain text.

There are other scenarios, however, where the use of SecureString is recommended, because the sensitive data is created by the program itself and should not remain in memory after it's done working with it. For instance, creating a SharePoint site programmatically, or transferring authentication credentials from one system to another.

Back in the good old days, it was easier to ensure that the lifetime of sensitive data was as short as possible. It could be allocated on the stack and cleared as soon as the program was done using it:

char secret[512]; generate_secret(secret, sizeof(secret)); do_something_with(secret); memset(secret, 0, sizeof(secret)); // Secret data is now gone.

Such an approach is not possible with managed strings, though, mainly because:

<ul><li>They're not allocated on the stack,</li> <li>They're immutable, so they cannot be cleared,</li> <li>They're not disposable, so there is no guarantee about the time when the GC will free the data. It might even never be freed, depending on memory conditions.</li> </ul>

SecureString tries to solve that problem by being mutable and disposable, which allows one to write:

using (SecureString secret = new SecureString()) { GenerateSecret(secret); secret.MakeReadOnly(); DoSomethingWith(secret); } // Secret data is now gone.

Answer2:

SecureString is best used for allocating network credentials for direct calls between systems. It's a given in the web arena that if the credential came in through the web that it's in plaintext somewhere, but if you have to send that credential back out through a standard credential call (ftp, directory services, etc), then using SecureString does not hurt as a passing method. While you're correct that the string is already on your server system in plain text, you can at least reduce the footprint between systems. If you're only using this password locally, then I would agree that SecureString is probably not terribly necessary.

Good security habits, though, are never really a waste of time.

Answer3:

I think you have the basics of it. SecureString is designed from the point of view of being on the Client Side. So for a WPF/Winforms app (and maybe Silverlight, can't remember if it is in there) it is worth tons while for a server side app, not as much due to not being the first to handle the string.

Answer4:

The only time I flag the missing use of SecureString when performing secure code reviews, are in instances where the data may be encrypted by the application and reused.

For instance, when a website backend needs to communicate with a third party or another internal resource that requires credentials. Since these can't be hashed, I would use the SecureString when needing to build the request (which should be over TLS as well).

Another alternative is to use the <a href="https://msdn.microsoft.com/en-us/library/ms995355.aspx" rel="nofollow">Windows Data Protection API</a> if possible.

Note that the purpose of SecureString is to keep the contents in memory for as short a time as possible.

Answer5:

If I am not mistaken, you can use the following solution to keep input out of the string management of the CLR: <a href="https://stackoverflow.com/questions/17072767/web-api-how-to-access-multipart-form-values-when-using-multipartmemorystreampro" rel="nofollow">Web API: how to access multipart form values when using MultipartMemoryStreamProvider?</a>

Only read the FormData in the ExecutePostProcessingAsync(..) method as ReadAsByteArrayAsync() and it should never become a string on the way.

You still need https to keep the input secure on the way.

Recommend

  • Inserting null columns into a scipy sparse matrix in a specific order
  • how to define scope of Int
  • How the C++0x standard defines C++ Auto multiple declarations?
  • How to navigate between different html pages in Windows 8 Metro application using javascript?
  • Implementation of monitors with semaphores
  • Django: DRY principle and UserPassesTestMixin
  • Passing information to server-side function in a Google Docs Add On
  • Deduce parent class of inherited method in C++
  • Detection of framework usage on Mac system?
  • Django return user model id with L
  • What's the syntax to inherit documentation from another indexer?
  • Retrieving specified columns from a list of csv files to create a data data frame in R
  • Fail:(TESTMODE) Transactions of this market type cannot be processed on this system
  • Filter strings with regex before casting to numeric
  • Laravel: Getting Session ID oddly truncates when using foreach
  • C# program and C++ DLL compiled for 32-bit system crash on 64-bit system
  • How do I access an unhandled exception in an MVC Error view?
  • Custom Tabgroup Appcelerator
  • iOS: Detect app start via notification press
  • Google Custom Search with transparent background
  • Initializer list vs. initialization method
  • How do I change content of ComboFieldEditor?
  • Is there any way to access browser form field suggestions from JavaScript?
  • Get object from AWS S3 as a stream
  • Sony Xperia Z Tablet not found by adb
  • How to redirect a user to a different server and include HTTP basic authentication credentials?
  • Javascript convert timezone issue
  • vba code to select only visible cells in specific column except heading
  • Why is the timeout on a windows udp receive socket always 500ms longer than set by SO_RCVTIMEO?
  • Weird JavaScript statement, what does it mean?
  • jQuery tmpl and DataLink beta
  • Do I've to free mysql result after storing it?
  • How to include full .NET prerequisite for Wix Burn installer
  • SQL merge duplicate rows and join values that are different
  • How do you join a server to an Active Directory (domain)?
  • embed rChart in Markdown
  • How to get NHibernate ISession to cache entity not retrieved by primary key
  • How can I use `wmic` in a Windows PE script?
  • Unable to use reactive element in my shiny app
  • To Get the radio button value in ruby on rails