SecureStore icon indicating copy to clipboard operation
SecureStore copied to clipboard

Implement SafeOrbit's Safe<T> and memory protection

Open micah686 opened this issue 1 year ago • 2 comments

Could you look into implementing SafeOrbit(https://github.com/undergroundwires/SafeOrbit) into SecureStore? That would allow using SafeStrings and SafeBytes to prevent against reading secrets in memory,as well as defend against injection.

micah686 avatar Aug 13 '22 21:08 micah686

Hi @micah686 - thanks for raising this issue and bringing that my library to my attention! In-memory protection of secrets is an important but much underappreciated topic!

Currently SecureStore doesn't make any guarantees about in-memory protection, but there is already some sort of best-effort attempt to protect against processes attempting to scrape memory for secrets. The stored secrets are stored encrypted in memory and the master decryption key (read from a keyfile or derived from a password) is stored in our own SecureBuffer type (because Microsoft doesn't have a binary corollary to SecureString).

We previously exposed a SecureString-based API for inputting the password (although you will likely not be using a password in production) but ran into the aforementioned best-effort limitations with just how securely the password could be protected since Microsoft's own password derivation APIs (we use PBKDF2) take a plain string as input (requiring that the secret be at least temporarily marshalled to unsecure memory). Going through the git history, it seems that when the library was ported to .NET Core back in 2017, there was no System.Security.SecureString available for .NET Core, so that API was dropped - I see that there is a SecureString implementation for .NET Core/.NET 5+ available (.netstandard 1.3 target) so that's something we can potentially revisit.

I'll have to read more about the injection detection/prevention that the library you shared exposes. I'm not sure if it's safe for someone adding a dependency on SecureStore to automatically end up with something like that enabled, given the immense scope of some of the web projects that are using SecureStore and just how many things could - potentially - break. But I could be overestimating the number of cases where process injection is being intentionally utilized, especially for .NET Core/.NET 5+ projects where code cleanliness and portability are much greater concerns than with the old .NET Framework projects. (Of course, projects can also opt into SafeOrbit/whatever's injection detection/prevention themselves.)

Ultimately though, for 99.99% of users there's always going to be some leakage happening when secrets are retrieved as I'm not aware of any major APIs/SDKs that take secrets as SecureString (or SecureBuffer, in the case of binary secrets).

Just as an FYI, currently the most secure way to use the SecureStore library would be via a keyfile (which is read directly into a SecureBuffer without going into non-protected memory) and disposing the SecretsManager instance as soon as you can (so the memory used by the SecureBuffer instances can be shredded).

mqudsi avatar Aug 13 '22 21:08 mqudsi

Thanks for the detailed description. I figured I would bring the library to your attention, since it's relevant to dealing with secrets in memory (even if temporarily). In regards to the injection protection, you could have that as an option, so any programmers could turn it on or off as required by their application. You could also potentially implement the SafeString and SafeBytes without implementing the memory injection detection if necessary.

micah686 avatar Aug 13 '22 21:08 micah686