In my WPF application I want to allow administrators to test a database connection using integrated security for various other users. So I have a form that allows the admin to enter the domain, username and password and then test it. I am able to securely handle the password right up until I call LogonUser
in the advapi32.dll
which takes a string password
LogonUser(UserName, Domain, Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref UserHandle)
I have written a utility function which converts the SecureString to a string as safe as possible, and then im calling it on the password in the LogonUser call:
LogonUser(UserName, Domain, Helper.ConvertSafely(Password), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref UserHandle)
Since the signature for LogonUser takes a string, unless LogonUser is taking proper care of the password in its execution, it could still be on my call stack in plain text after the call returns. Is there a more secure way to impersonate a user in which i can be confidant the PW is secure the whole time?
Basically all I need is a WindowsImpersonationContext
but i would like to aquire it without the password ever being in plain text.
Impersonation is the ability of a thread to execute in a security context that is different from the context of the process that owns the thread. When running in the client's security context, the server "is" the client, to some degree.
Defines security impersonation levels. Security impersonation levels govern the degree to which a server process can act on behalf of a client process. Anonymous. The server process cannot obtain identification information about the client, and it cannot impersonate the client.
Impersonation allows the service to act as the client while performing the action. Delegation allows a front-end service to forward the client's request to a back-end service in such a way that the back-end service can also impersonate the client.
Inside your managed application you can make use of the SecureString class to handle sensitive information. There is usually no need to roll your own secure string mechanism.
Just before you pinvoke into LogonUser you are then passing the unmanaged copy of
the SecureString password. You use the Marshal.SecureStringToGlobalAllocUnicode
Method for this. Thus there is never a managed object in your app domain representing the password.
You can find example code in this article.
If you require even more security I would suggest to disallow direct database connection from you wpf clients. You can introduce a middle tier. Security is thus shifted away from the clients to this one server. Communication between Client and App-Server is encrypted and only the app server talks to the database.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With