I have come across a problem with binding to a PasswordBox
. It seems it's a security risk but I am using the MVVM pattern so I wish to bypass this. I found some interesting code here (has anyone used this or something similar?)
http://www.wpftutorial.net/PasswordBox.html
It technically looks great, but I am unsure of how to retrieve the password.
I basically have properties in my LoginViewModel
for Username
and Password
. Username
is fine and is working as it's a TextBox
.
I used the code above as stated and entered this
<PasswordBox ff:PasswordHelper.Attach="True"
ff:PasswordHelper.Password="{Binding Path=Password}" Width="130"/>
When I had the PasswordBox
as a TextBox
and Binding Path=Password
then the property in my LoginViewModel
was updated.
My code is very simple, basically I have a Command
for my Button
. When I press it CanLogin
is called and if it returns true it calls Login
.
You can see I check my property for Username
here which works great.
In Login
I send along to my service a Username
and Password
, Username
contains data from my View
but Password
is Null|Empty
private DelegateCommand loginCommand;
public string Username { get; set; }
public string Password { get; set; }
public ICommand LoginCommand
{
get
{
if (loginCommand == null)
{
loginCommand = new DelegateCommand(
Login, CanLogin );
}
return loginCommand;
}
}
private bool CanLogin()
{
return !string.IsNullOrEmpty(Username);
}
private void Login()
{
bool result = securityService.IsValidLogin(Username, Password);
if (result) { }
else { }
}
This is what I am doing
<TextBox Text="{Binding Path=Username, UpdateSourceTrigger=PropertyChanged}"
MinWidth="180" />
<PasswordBox ff:PasswordHelper.Attach="True"
ff:PasswordHelper.Password="{Binding Path=Password}" Width="130"/>
I have my TextBox
, this is no problem, but in my ViewModel
the Password
is empty.
Am I doing something wrong or missing a step?
I put a breakpoint and sure enough the code enter the static helper class but it never updates my Password
in my ViewModel
.
Sorry, but you're doing it wrong.
People should have the following security guideline tattooed on the inside of their eyelids:
Never keep plain text passwords in memory.
The reason the WPF/Silverlight PasswordBox
doesn't expose a DP for the Password
property is security related.
If WPF/Silverlight were to keep a DP for Password
it would require the framework to keep the password itself unencrypted in memory. Which is considered quite a troublesome security attack vector.
The PasswordBox
uses encrypted memory (of sorts) and the only way to access the password is through the CLR property.
I would suggest that when accessing the PasswordBox.Password
CLR property you'd refrain from placing it in any variable or as a value for any property.
Keeping your password in plain text on the client machine RAM is a security no-no.
So get rid of that public string Password { get; set; }
you've got up there.
When accessing PasswordBox.Password
, just get it out and ship it to the server ASAP.
Don't keep the value of the password around and don't treat it as you would any other client machine text. Don't keep clear text passwords in memory.
I know this breaks the MVVM pattern, but you shouldn't ever bind to PasswordBox.Password
Attached DP, store your password in the ViewModel or any other similar shenanigans.
If you're looking for an over-architected solution, here's one:
1. Create the IHavePassword
interface with one method that returns the password clear text.
2. Have your UserControl
implement a IHavePassword
interface.
3. Register the UserControl
instance with your IoC as implementing the IHavePassword
interface.
4. When a server request requiring your password is taking place, call your IoC for the IHavePassword
implementation and only than get the much coveted password.
Just my take on it.
-- Justin