Secure Inter-Process Communication for sharing Sensitive Information

Viewed 1390

I have a scenario where a C#.NET program must be supplied a secret that is derived from a Username/Password combination. This secret is non-reversible (think of it like a hash) but has the requirement that the secret can only be created with a .NET library.

The problem here is that there is the program that actually contains the username/password is different than the program that needs the secret and is not a .NET program, so the information has to be sent through some IPC.

It is worth noting that the program the has the username/password keeps them in memory for as long as the user is logged in. I realize that this itself is very insecure, but it isn't something that I am able to change.

I am looking for a way for the C#.NET program to get the secret as securely as possible.

Two options that I came up with are to use a Named Pipe to transfer the username/password directly from one application to the other, or to use COM components so the first application can send the username/password to the COM component, which can compute the secret and write it to a location that can be read later by the second application.

for the Named Pipe method I would expect the credential requesting component to look something like the following

using (var a = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous, TokenImpersonationLevel.Impersonation))
{
    var requestString = new StreamString(a);
    var credString = new StreamString(a);

    await a.ConnectAsync();

    a.ReadMode = PipeTransmissionMode.Message;

    requestString.WriteString(JsonConvert.SerializeObject(new CredentialRequest()));

    var cred = JsonConvert.DeserializeObject<Credential>(credString.ReadString());

    var secret = await CreateSecret(cred.Username, cred.Password);
    a.Close();
}

Based on that, the side opposite side of the pipe should be pretty obvious.

For the COM solution I am thinking that I would create an object that has the following method

public void ComputeAndStoreSecret(string username, string password)
    {

        var secret = CreateSecret(username, password);

        using (var applicationStorageFileForUser = IsolatedStorageFile.GetUserStoreForAssembly())
        {
            using (var applicationStorageStreamForUser = new IsolatedStorageFileStream("secret_store.txt", FileMode.Create, applicationStorageFileForUser))
            {
                using (StreamWriter sw = new StreamWriter(applicationStorageStreamForUser))
                {
                    sw.WriteLine(secret);
                }
            }
        }

    }

There would also be a COM component that reads from that storage location and returns the secret.

I am basically looking for any insight as to why I would want to use one of these techniques over the other or maybe consider any other options (RPC, Mailbox, etc.)

Some things that I have discovered/considered

  • Named Pipe solution is vulnerable to Pipe Squatting
  • Named Pipes require username/password to leave process space of the first application
  • Storage Location of secret using COM solution can be seen and edited by everything
  • Isolated File Storage in COM solution is not intended to be used for secret information

I realize that neither of these solutions are secure, but I am looking for a solution that at least doesn't make it drastically more insecure.

0 Answers
Related