How to Bind to a Passwordbox in Mvvm

How to bind to a PasswordBox in MVVM

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

PasswordBox and MVVM

Personally I just pass the entire PasswordBox control to my LoginCommand

I know it breaks MVVM because the ViewModel layer now references a View-specific object, but I think in this specific case it's OK.

So I might have XAML that looks like this:

<Button Content="Login" 
Command="{Binding LoginCommand}"
CommandParameter="{Binding ElementName=MyPasswordBox}" />

And a LoginCommand that does something like this:

private void Login(object obj)
{
PasswordBox pwBox = obj as PasswordBox;

SomeBlackBoxClass.ValidatePassword(UserName, pwBox.Password);
}

I suppose you could also run some kind of encryption algorithm on the value and compare the hash of that value to the hash of the user's password too

private void Login(object obj)
{
PasswordBox pwBox = obj as PasswordBox;
var encryptedPassword = SomeLibrary.EncryptValue(pwBox.Password, someKey);

if (encryptedPassword == User.EncryptedPassword)
// Success
}

I'm no expert on the PasswordBox control or security, but I do know that you don't want to be storing the user's password in plain text anywhere in memory within your application

(Technically, it's stored as plain text in PasswordBox.Password - you can use something like Snoop to verify this if you want - however typically the PasswordBox doesn't exist for longer than it takes the user to login, and the actual "password" is just text entered by the user, which may or may not be correct. A keylogger could get you the same information.)

WPF MVVM PasswordBox Binding

You simply can't set the SecurePassword. It is a readOnly Property. If you want to fill the PasswordBox, you have to set the Unsecure String Password Property.

Bind a WPF passwordbox

The Password property is not a dependency property -- for security reasons. You can easily get the plain-text password, though.

XAML:

<PasswordBox
x:Name="passwordBox"
PasswordChanged="OnPasswordChanged" />

Code-behind event handler:

private void OnPasswordChanged(
object sender,
RoutedEventArgs e)
{
Debug.WriteLine(passwordBox.Password);
}

Updates

  • Samuel Jack describes how to bind to a PasswordBox using attached properties
  • A discussion on security risk

PasswordBox Binding

Interesting.

look at this blog post and see if it is helping you.
http://blog.functionalfun.net/2008/06/wpf-passwordbox-and-data-binding.html

Apparently the link is dead now so here is the original solution (found here):

You can use attached properties to create a helper like this:


public static class PasswordHelper
{
public static readonly DependencyProperty PasswordProperty =
DependencyProperty.RegisterAttached("Password",
typeof(string), typeof(PasswordHelper),
new FrameworkPropertyMetadata(string.Empty, OnPasswordPropertyChanged));

public static readonly DependencyProperty AttachProperty =
DependencyProperty.RegisterAttached("Attach",
typeof(bool), typeof(PasswordHelper), new PropertyMetadata(false, Attach));

private static readonly DependencyProperty IsUpdatingProperty =
DependencyProperty.RegisterAttached("IsUpdating", typeof(bool),
typeof(PasswordHelper));


public static void SetAttach(DependencyObject dp, bool value)
{
dp.SetValue(AttachProperty, value);
}

public static bool GetAttach(DependencyObject dp)
{
return (bool)dp.GetValue(AttachProperty);
}

public static string GetPassword(DependencyObject dp)
{
return (string)dp.GetValue(PasswordProperty);
}

public static void SetPassword(DependencyObject dp, string value)
{
dp.SetValue(PasswordProperty, value);
}

private static bool GetIsUpdating(DependencyObject dp)
{
return (bool)dp.GetValue(IsUpdatingProperty);
}

private static void SetIsUpdating(DependencyObject dp, bool value)
{
dp.SetValue(IsUpdatingProperty, value);
}

private static void OnPasswordPropertyChanged(DependencyObject sender,
DependencyPropertyChangedEventArgs e)
{
PasswordBox passwordBox = sender as PasswordBox;
passwordBox.PasswordChanged -= PasswordChanged;

if (!(bool)GetIsUpdating(passwordBox))
{
passwordBox.Password = (string)e.NewValue;
}
passwordBox.PasswordChanged += PasswordChanged;
}

private static void Attach(DependencyObject sender,
DependencyPropertyChangedEventArgs e)
{
PasswordBox passwordBox = sender as PasswordBox;

if (passwordBox == null)
return;

if ((bool)e.OldValue)
{
passwordBox.PasswordChanged -= PasswordChanged;
}

if ((bool)e.NewValue)
{
passwordBox.PasswordChanged += PasswordChanged;
}
}

private static void PasswordChanged(object sender, RoutedEventArgs e)
{
PasswordBox passwordBox = sender as PasswordBox;
SetIsUpdating(passwordBox, true);
SetPassword(passwordBox, passwordBox.Password);
SetIsUpdating(passwordBox, false);
}
}

Use it:

<PasswordBox w:PasswordHelper.Attach="True" 
w:PasswordHelper.Password="{Binding Text, ElementName=plain, Mode=TwoWay}"
Width="100"/>

MVVM, Behavior and passwordBox

Just moved class PasswordBehavior into view code behind and create Property "Password" in VM:

    private string _Password;
public string Password
{
get { return _Password; }
set { _Password = value; NotifyPropertyChanged("Password"); }
}

All works as expected.

PasswordBox with MVVM

For security reasons the Password property is not a dependency property and therefore you can't bind to it. Unfortunately you'll need to perform the binding in the code behind the old fashioned way (register for OnPropertyChanged event and update the value through code...)


I quick search brings me to this blog post which shows how to write an attached property to sidestep the issue. Whether this is worth doing or not though really depends on your aversion to code-behind.

How to bind to a PasswordBox in MVVM

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



Related Topics



Leave a reply



Submit