Click here to Skip to main content
15,861,366 members
Articles / Desktop Programming / WPF
Article

Passwords in WPF: How to find yours and how to prevent it being found

Rate me:
Please Sign up or sign in to vote.
4.21/5 (23 votes)
23 Nov 2008CPOL4 min read 77.4K   984   31   18
How I can find your password and how to prevent it.

Introduction

Windows Presentation Foundation introduces a new control for entering passwords, but unfortunately, like the TextBox of Win32, it is not too complicated to reveal the magic word hidden under the asterisks.

The fastest method is to analyze the VisualTree (the tree view of controls) with Snoop and go directly to read the password control.

Unsecure_WPF_LogOn.jpg

In seconds, the password can be found, but we can make life more difficult for prying eyes with a few lines of code.

First, how can we hide a value of a property from Snoop?

Snoop displays both the dependency property and the CLR property, but we will create a dependency property specifically to trick the program (at least in the current version).

Create a simple Window in a new WPF project called MainWindow and to insert a normal DependencyProperty called MyString1 with an easily recognizable default value:

C#
public partial class MainWindow : Window
{
   public MainWindow()
   {
      InitializeComponent();
   }
   public static readonly DependencyProperty MyString1Property = 
      DependencyProperty.Register(
      "MyString1",
      typeof(string),
      typeof(MainWindow),
      new FrameworkPropertyMetadata("default value of MyString1")
   );
   public string MyString1
   {
      get { return (string)GetValue(MyString1Property); }
      set { SetValue(MyString1Property, value); }
   }
}

Snooping the MainWindow (jargon that means opening Snoop, selecting our running application, clicking "Snoop this application", and looking in the tree view element MainWindow), we can see and change the default value MyString1. Add this code to the constructor of the class:

C#
MyString1 = "nuovo valore";

The new value is shown by Snoop on Window load, and everything works properly.

We now create a new DependencyProperty called MyString2, inserting the code for a normal CLR property in the CLR "wrapper" code:

C#
public static readonly DependencyProperty MyString2Property = 
   DependencyProperty.Register(
   "MyString2",
   typeof(string),
   typeof(MainWindow),
   new FrameworkPropertyMetadata("default value of MyString2")
);

string _myString2 = "value of internal field of MyString2";
public string MyString2
{
   get { return _myString2; }
   set { _myString2 = value; }
}

How will Snoop behave now with MyString2? Simple, it will continue to read the DependencyProperty managed by the WPF property system while "the code" will use the CLR wrapper. In other words, Snoop reads MyString2 with the method GetValue, while the code reads MyString2 through _myString2.

Perfect, we found how to get away from Snoop!

To better exemplify the enclosed source code AntiSnoopSample, a small program that I wrote to show the potential of a property dependency "badly written", I include a CLR property MyString3 to show that Snoop correctly reads the property dependency.

With what we have learned, let’s get back to our problem, analyzing the control PasswordBox; we notice immediately that it is marked with sealed (can not be inherited). This excludes a direct derivation of our control that stores the password in a field not easily readable by Snoop .

Object_Browser_PasswordBox.jpg

At this point, we can choose two roads: derive "our PasswordBox" from a TextBox control, or try to work around this limitation by managing the PasswordChanged event.

The event PasswordChanged is triggered when the property value is changed. Then, we can copy the character inserted in a private field to our window, and replace the password of PasswordBox with asterisks (in the attached code, the password is replaced with asterisks). Now, we try to recover our password with Snoop: we only get asterisks. In our application, we should use the private field (in the code, this.pwd) to use the clear password.

Snoop_secure_WPF_LogOn.jpg

This choice has several limitations. Because the control PasswordBox is "closed", it is not possible to detect the position of the cursor text. It is not possible to replicate the password in private if it was a pasted text or if you press the Delete key or Backspace.

We will have to simply delete the entire password under any of these conditions. But in some scenarios, this could go well.

If we choose the path of derivation instead, we have greater flexibility, but also greater "responsibility": the code will have to locate the position of changes in the password and reproduce it in a field not visible in Snoop.

I implemented the control SecurePasswordBox derived from a TextBox for a illustration. The whole logic is executed in the override of the OnTextChanged event and a clear password is recoverable through the usual Text property of the control. Snoop does not read the Text property of their own SecurePasswordBox because, as explained, its CLR wrapper implements a normal private field instead of calling SetValue / GetValue.

Snoop calling GetValue effectively reads "base.Text" or the text contained in the inherited control but set to a series of asterisks, and our privacy is safe from the malicious use of Snoop. Mission accomplished.

NB: These solutions are not be definitive, a modified version of Snoop could very well read passwords even in these cases, or the attacker could analyze the memory of the program and find the password in each case. But, these solutions will defend the security of the application.

The advice is not to allow the arbitrary execution of any program in Full Trust in sensitive environments to avoid unpleasant surprises.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Other
Italy Italy
Software Researcher at the University of Parma (Italy)

Comments and Discussions

 
QuestionQuestion Regarding Code Pin
Taylor Leese26-Nov-09 2:12
Taylor Leese26-Nov-09 2:12 
GeneralMy vote of 5 Pin
Dr.Luiji18-Dec-08 9:14
professionalDr.Luiji18-Dec-08 9:14 
GeneralComments Pin
Greizzerland25-Nov-08 5:48
Greizzerland25-Nov-08 5:48 
GeneralMy vote of 1 Pin
xliqz24-Nov-08 6:16
xliqz24-Nov-08 6:16 
QuestionWhat about using something like a substitution cipher? Pin
supercat924-Nov-08 5:53
supercat924-Nov-08 5:53 
GeneralRe: What about using something like a substitution cipher? Pin
supercat924-Nov-08 8:31
supercat924-Nov-08 8:31 
GeneralMy vote of 1 Pin
Simon P Stevens24-Nov-08 5:45
Simon P Stevens24-Nov-08 5:45 
General[Message Deleted] Pin
Pete Souza IV24-Nov-08 3:37
professionalPete Souza IV24-Nov-08 3:37 
GeneralUseless - my vote of 1 Pin
Marco Mastropaolo24-Nov-08 2:52
Marco Mastropaolo24-Nov-08 2:52 
When typing, it's safe to assume the user is not allowing someone snooping through third party tools -> if he isn't, the risk of keyloggers is much higher and, beside, there's little you can do anyway.

When showing a window (say, containing a password typed in a previous session) you should NEVER put the password text in a textbox. The password is readable whatever you do. It will be in clear text in the pagefile (unless you take special precautions), in RAM, and in the textbox data model of course. It takes just a window message to get it. Beside, this means you have stored the password somewhere instead of an hash of it - this might be necessary in many situations but means that anyone with admin access to the machine can get the cleartext password.

What you are doing is leaving the key under the carpet and making it more secure by nailing the carpet to the ground. And you left the door open anyway.
GeneralMy vote of 1 Pin
Bartosz Wójcik24-Nov-08 1:51
Bartosz Wójcik24-Nov-08 1:51 
GeneralThe article name should be how to protect password from Snoop Pin
Shivprasad koirala24-Nov-08 0:22
Shivprasad koirala24-Nov-08 0:22 
GeneralSorry, doesn't really serve a purpose Pin
William E. Kempf21-Nov-08 4:31
William E. Kempf21-Nov-08 4:31 
GeneralRe: Sorry, doesn't really serve a purpose Pin
Yogesh Jagota23-Nov-08 23:28
Yogesh Jagota23-Nov-08 23:28 
GeneralVery good Pin
Paul Conrad20-Nov-08 9:43
professionalPaul Conrad20-Nov-08 9:43 
GeneralRe: Very good Pin
Paul Conrad20-Nov-08 10:44
professionalPaul Conrad20-Nov-08 10:44 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.