Very closely related: How to protect strings without SecureString?
Also closely related: When would I need a SecureString in .NET?
Extremely closely related (OP there is trying to achieve something very similar): C# & WPF - Using SecureString for a client-side HTTP API password
The .NET Framework has class called SecureString. However, even Microsoft no longer recommends its use for new development. According to the first linked Q&A, at least one reason for that is that the string will be in memory in plaintext anyway for at least some amount of time (even if it's a very short amount of time). At least one answer also extended the argument that, if they have access to the server's memory anyway, in practice security's probably shot anyway, so it won't help you. (The second linked Q&A implies that there was even discussion of dropping this from .NET Core entirely).
That being said, Microsoft's documentation on SecureString does not recommend a replacement, and the consensus on the linked Q&A seems to be that that kind of a measure wouldn't be all that useful anyway.
My application, which is an ASP.NET Core application, makes extensive use of API Calls to an external vendor using the HttpClient class. The generally-recommended best practice for HttpClient is to use a single instance rather than creating a new instance for each call.
However, our vendor requires that all API Calls include our API Key as a header with a specific name. I currently store the key securely, retrieve it in Startup.cs, and add it to our HttpClient instance's headers.
Unfortunately, this means that my API Key will be kept in plaintext in memory for the entire lifecycle of the application. I find this especially troubling for a web application on a server; even though the server is maintained by corporate IT, I've always been taught to treat even corporate networks as semi-hostile environments and not to rely purely on corporate firewalls for application security in such cases.
Does Microsoft have a recommended best practice for cases like this? Is this a potential exception to their recommendation against using SecureString? (Exactly how that would work is a separate question). Or is the answer on the other Q&A really correct in saying that I shouldn't be worried about plaintext strings living in memory like this?
Note: Depending on responses to this question, I may post a follow-up question about whether it's even possible to use something like SecureString as part of HttpClient headers. Or would I have to do something tricky like populate the header right before using it and then remove it from memory right afterwards? (That would create an absolute nightmare for concurrent calls though). If people think that I should do something like this, I would be glad to create a new question for that.
SecureStringis encrypted on windows, on unix it's not. And once released the buffer containing it is released rather quickly (plus you could use unsafe code to zero out a string even w/o it). The actual problem withSecureStringis, that there is no easy way to construct it. You only have parameterless constructor (for constructing char by char) or via achar*or by anotherSecureString. Classical use case was to deserialize it from configuration file directly into it or char by char from UI.*.App.Configsupported encrypted strings/secrets, but the feature heavily relied on having specific certificates installed on the local machines certificate store (for encrypting/decrypting) which doesn't really well translate to Linux and docker Containers, so that feature isn't there on Non-Windwos OS'. If you really worry about it, you can create a string extension method that uses unsafe code to obtain a pointer and zero out the memory where the password was contained, you just need be really sure you never access that string again.string newString = new string(oldString). But imho its more trouble than its worth, better protect yourserver from people geetting there. You still gotta be careful when making dumps and sending these (to external companies for debugging) since these may appear in the dumps