views:

3505

answers:

8

Hi there,

I have come across a problem with binding to a passwordbox. It seems its 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 how to retrieve the password.

I basically have a property in my LoginViewModel for Username and Password, of course username is fine and is working as its 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"/>

As you can see i am binding to Password, but maybe its bind it to the static class..

Still a beginner here so i am really confused.

When i had the passwordbox as a textbox and Binding path=Password then the property in my LoginViewModel was updated.

Can anyone lend a hand or provide a better alternative?

My code is very simple, basically i have a command for my button that when i press it arrives and checks CanLogin (you can see i check my property for username here which works great) and if it returns true it calls Login..

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
        {


        }
    }
A: 

As you can see i am binding to Password, but maybe its bind it to the static class..

It is an attached property. This kind of property can be applied to any kind of DependencyObject, not just the type in which it is declared. So even though it is declared in the PasswordHelper static class, it is applied to the PasswordBox on which you use it.

To use this attached property, you just need to bind it to the Password property in your ViewModel :

<PasswordBox w:PasswordHelper.Attach="True" 
         w:PasswordHelper.Password="{Binding Password}"/>
Thomas Levesque
A: 

Hi, thanks for the reply.. THis is what i am doing ... here is my code

        <TextBox Text="{Binding Path=Username, UpdateSourceTrigger=PropertyChanged}"
        MinWidth="180"></TextBox>

        <PasswordBox ff:PasswordHelper.Attach="True" 
        ff:PasswordHelper.Password="{Binding Path=Password}" Width="130"/>

As you can see 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..

mark smith
Please use the comments or edit your question instead of adding an answer
Lars Truijens
Sorry... i will next time.
mark smith
+1  A: 

you can do it with attached property, see it.. http://stackoverflow.com/questions/1097235/passwordbox-with-mvvm

Rangel
+3  A: 

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

JustinAngel
Couldn't you use the SecureString in the VM for WPF to solve this problem? It doesn't seem like there is something for Silverlight.
Bryant
I agree with your intention and the message you are conveying but your answer implies that the password string is never in memory if you follow this approach. The value of the password will be in memory from the moment the user types it. Eliminating the property holding your passphrase is a good idea and will limit the copies of your password that get left laying around for the garbage collector to reap or that could perhaps be found by other managed and unmanaged code running as part of your program, but will not hide it altogether.
IanNorton
A: 

You find a solution for the PasswordBox in the ViewModel sample application of the WPF Application Framework (WAF) project.

However, Justin is right. Don't pass the password as plain text between View and ViewModel. Use SecureString instead (See MSDN PasswordBox).

jbe
The way that is used in Pop3SettingsView of WAF is funny. PasswordBox passwordBox = (PasswordBox)sender; if (ViewModel != null) { ViewModel.Pop3Password = passwordBox.Password; }Pop3Password of ViewModel is the string property. so, its not secure as well .. better to use the attached property
Michael Sync
+2  A: 

This works just fine for me.

<Button Command="{Binding Connect}" CommandParameter="{Binding ElementName=MyPasswordBox}"/>
Vladislav Borovikov
What about CommandParameter="{Binding ElementName=MyPasswordBox, Path=SecurePassword"} ?
LukeN
+1  A: 

Doesn't passing in the whole passwordbox control go against separating the view from the viewmodel?

Richie
A: 

I posted a GIST here that is a bindable password box.

Taylor Leese