Busting Password Managers: Separating User ID and Password POSTs

By Tim MalcomVetter, Paul Wowk ·

This is a continuation of our series on Busting Password Managers. Check out the first post here.

Hypothesis: If usernames and passwords are submitted in separate POST requests, then browsers will not save passwords.

The Technique: This method involves an extra form post back to the server. On the first post, the user submits only the username and the server keeps and associates that value with the session. On the second post, the user submits only the password. To test this out, we again started with the canned Visual Studio 2013 ASP.NET MVC C# project. The source code for this test can be downloaded from https://github.com/pvwowkfn/AutoCompleteBlog/tree/SplitAuth.

The first thing we did was to clone the LoginModel class in AccountModels.cs and create a Step1 and Step2 copy, with Step1 not containing the password field:

We also went ahead and did the same to the RegistrationModel class since we knew we would be splitting that into two separate POSTs as well:

Then we cloned the Login.cshtml view, naming the copy as LoginStep2.cshtml. We updated the original Login.cshtml to remove the password field and change the form’s target to post to LoginStep2:

On the LoginStep2.cshtml view, we pointed the form’s action as a POST to the original Login controller, and we removed the text fields for the username, leaving only the password field:

We repeated this on the Register views. The original Register.cshtml view was modified to point to the RegisterStep2 controller as a POST, and only the username field remained:

On the RegisterStep2 view, we pointed back to the Register controller as a POST and left only the password and password confirmation fields:

In the AccountController.cs file, we needed to make two controllers for each step of the Login and Registration process. For the LoginStep2 controller, we simply put the username into the session. For convenience, we pass along the “remember me” checkbox’s value as well:

Then in the Login controller, we retrieve the username out of session and perform the authentication call:

We repeated this process for the Registration controller as well. The first copy of the existing controller is called RegisterStep2, and it also persists the username in session:

Then in the Register controller, we retrieve the username from session and perform the account creation request:

While this worked on a few of the browsers, it did not work on all. Firefox was smart enough to detect what was going on:

The caveat, of course, is that other browsers could become more sophisticated at detecting passwords in future releases as well.

Successfully works on:

No

Yes

Yes

Yes

Yes

Previous Articles