In this short post I wanna share just a way to pass a secret to a specific service.
Let's suppose we have a service class that it needs to work of a secret (e.g. a password) or something containing sensitive data (e.g. a connection string).
In this scenario, an instinctive approach could be something like shown below, where a class receive a plain text secret in the constructor and provides a service using this secret.
public class DummyService
{
private string _Secret;
public DummyService(string secret)
{
_Secret=secret;
}
private void DoSomenthing(string secret)
{
//Doing stuff
}
public void ProvideService()
{
DoSomenthing(_Secret);
}
}
But what's wrong with this approach? Eventhough apparently it seems all OK, actually there is a security problem:
The secret is passed in plain text and stored in memory as is, not encrypted, during all the life cycle of the service, and so it could be (potentially) read by some utility able to dump and analyze the memory.
How can we solve this problem? (or how can we reduce this risk?)
A safer approach could be to avoid passing the plain text secret to the constructor but just a way to get it. The idea is to run a function to get this information.
A delegate could be a solution because it's just we need, a function pointer giving us a way to represent a method to get the secret without store it in memory.
Take a look at this second version of our DummyService where we inject a secret reader (our delegate).
public class DummyService
{
private Func<string> SecretReader;
public DummyService(Func<string> secretReader)
{
SecretReader = secretReader ?? throw new ArgumentNullException(nameof(secretReader));
}
private void DoSomenthing(string secret)
{
//Doing stuff
}
public void ProvideService()
{
DoSomenthing(SecretReader.Invoke());
}
}
In this version of our DummyService the injected delegate (the secret reader) could implement a decryption function to get our plain secret.
In this way we have reduced a lot the plain secret memory life time because the secret will be used just when it'll be necessary reducing so the probability that it could be read in memory by using some utility.
See you
AM