Summary of our AsiaCCS paper on implementing a password manager which protects users against XSS attackers

Much of our work focusses on Cross-Site Scripting vulnerabilities. These vulnerabilities are often used by an attacker to steal authentication data such as session cookies and subsequently use the service in the name of his victim. However, we identified another attack in which abusing a XSS vulnerability might come in handy for an attacker: automatically stealing passwords from the victim’s password managers.

Underlying security issue

The scenario in this case is quite straight forward. As discussed by Mozilla’s Justin Dolske, password managers work in a simple manner. Whenever a user enters his credentials into a login form and subsequently posts it, the browser’s password manager is invoked and prompts the user to agree to storing of these credentials. When the user later comes back to the same login page, the password manager scans the document to determine where the login form is and if it is found, automatically fills out the credentials previously stored. This however comes with inherent security issues attached to it since the credentials are inserted into the document, and thus are accessible via the Document Object Model (or short DOM). The DOM is an API that enables JavaScript to interact with the document, allowing JavaScript to read and modify the document’s structure as it wishes.

Automatically attacking password managers

This is precisely where the Cross-Site Scripting attacker comes into play. The attack is conducted in three steps (which is also shown in the figure below):

  1. The attacker injects a form with a username and password field into the vulnerability document.
  2. The password manager detects the form and automatically (as discussed above) inserts the credentials into the fields.
  3. In the final step, the attacker’s injected code uses the DOM to retrieve the username and password and subsequently sends both back to the attacker’s server.

xsspassword

Factors for the success of these attacks

The degree to which an attack on vulnerable pages can be automatically conducted depends on multiple implementational details. In our work, we identified five of these factors:

  1.  URL matching: The first factor we identified was whether password managers check the URL of the form they insert credentials into. If credentials are merely stored alongside the origin (protocol, domain and port) of the page they were entered into, a XSS vulnerability on a document on said domain is sufficient for an attacker to mount the attack previously described. If the exact URL is stored, the attacker still has the option to either load the login page in a frame or open a popup with it. If the password managers inserts credentials in these viewports, the attacker can still retrieve the data, as the Same-Origin Policy is fulfilled and thus, access between frames is permitted.
  2. Form matching: The second factor we found is form matching, i.e., if the password manager stores the structure and/or the form’s target. This mainly is relevant for simple automation since an attacker could potentially attack a number of different domains with a minimal form (consisting only of two input fields, one text and one password field). Regardless, an attacker might also choose to build a form that perfectly matches the original one in a targeted attack against a given site.
  3. Autofilling frames: as discussed for URL matching, an attacker is capable of loading the login page in a frame if strict URL matching is employed. However, if a password manager refuses to insert credentials into forms inside frames, the attacker has to open a popup, thus loosing a certain amount of stealthiness in his attack. Apart from that, autofilling into frames makes automation much easier since the attacker can include multiple frames on a site under his control to retrieve the password data from many domains at a time.
  4. User interaction: one show stopper is obviously user interaction. If a password manager requires user interaction, attacks cannot be automated or at least require some form of social engineering for the victim to click on the corresponding “insert credentials” button.
  5. Autocomplete attribute: The autocomplete attribute was recently added with HTML5 and according to the spec, setting it to the “off keyword indicates […] that the control’s input data is particularly sensitive “. Thus, whenever a browser encounters such an attribute, it should not offer to store the sensitive data that was entered into the fields. (Quoting the WhatWG wiki: “Otherwise, the user agent should not remember the control’s value, and should not offer past values to the user.”). If however this is ignored in storing the credentials and only observed when inserting the stored data, an attacker is able to craft a form of his own with autocomplete=”on” for all fields and thus steal the secret data.

Analyzing the current generation of built-in password managers

With the aforementioned factors in mind, we conducted an analysis of six browsers, namely Chrome 31, Internet Explorer 11, Firefox 25, Opera 18, Safari 7 and the Maxthon Cloud Browser (version 3). Although the latter might not be as well-known as the rest, it is offered to users installing the latest versions of Windows when asked for their browser choice. Hence, we chose to include it in our analysis. The results of the analysis are shown in the following table:

Browser URL matching form matching Autofilling frames User interaction Autocomplete attribute
Chrome 31 No No Yes No partially
IE 11 Yes No No Yes Yes
Firefox 25 No No Yes No Yes
Opera 18 No No Yes No partially
Safari 3 No No Yes No Yes
Maxthon 3 No No Yes No No

As we see, the only browser that performs URL matching is Microsoft’s Internet Explorer, whereas the worst-case example is Maxthon. The browser only stores the second-level domain along with the credentials, meaning that a XSS on a given sub-domain, even with a different protocol and port, is sufficient to steal the passwords. IE is the most secure with respect to autofilling frames and user interaction as well. Most interestingly are the findings related to the autocomplete attribute in Chrome and Safari. We found that if just one field of a form has the autocomplete attribute not set to “off”, the credentials are stored. Although they are not automatically inserted into the field afterwards (in these cases, autocomplete is adhered to), this allows an attacker to craft his own form and trick the password manager into filling out the form.

This shows that there in most browsers, attacks against the password manager are easily achieved. Apart from Internet Explorer, none of our test subjects required user interaction or did URL matching of any sort.

Our proposed solution

The underlying cause for the attack we described earlier is the fact that password managers are implemented such that they insert credentials into forms (and the DOM) where they can be accessed by JavaScript. Although this is desirable for Web developers, it allows an XSS attacker to steal the stored credentials.

Looking at this, we see a mismatch in the notion of what a password manager should do (i.e. aid the user in the authentication process)  and what is does (i.e. insert credentials into forms). We therefore propose to align notion and implementation of passwords to protect them from automated, XSS-based attacks.

Inserting the passwords into fields is unnecessary, since they are typically only needed when the login request is sent to the server. Our approach therefore aims at doing just that. The following figure outlines the current implementation (upper part) and our proposed solution.

oursolution
Instead of inserting the password into the corresponding field, our implementation only inserts a nonce into the password field. This nonce may be accessed by the attacker since it is completely independent of the password that was originally stored. When the request is sent to the server, our prototype (built as a Firefox extension) detects the nonce and replaces it with the actual password. Thus, the stored password is sent to the server but not accessible by JavaScript. We also apply restrictions, namely strict matching of the target URL (so the attacker cannot send the credentials to his own server) as well as only replacing the nonce in POST parameters (such that an attacker may not ascertain the password by determining the URL the data sent to. In GET requests, all parameters are appended to the URL and thus might leak the password).

Functional evaluation

To prove that our approach is sound, we conducted an analysis of password fields on the Alexa Top 4,000. We used natural language to determine the location of logins (such as the keywords “login” or “sign in” in the links contained on the entry page). In total, we found 2,143 domains with login fields. Although we are sure that is number is not the complete amount of pages which have a login field within the top 4,000 domains, we believe that it is a sufficiently large data set. In our analysis, we found that 325 domains use JavaScript to access the password field and some manner. Manual analysis showed that out of these, 96 domains took the field inputs and sent them to a server using XHRs. Out of these, we found

  • 23 domains that hashes the password field’s input before sending it to the server,
  • 1 domain that applied base64 encoding on the password
  • and 6 domains which  use GET requests to send the data to the server.

The remaining domains only checked whether data was present in the fields before posting the form and thus do not cause incompatibilities with our proposed solution. With respect to the data set we see that only 30 out of 2,143 domains are incompatible with our approach, amounting to an incompatibility rate of just 1,4%.  We therefore believe that adoption is feasible, as we have shown with our proof of concept implementation for Firefox.

Resources

Leave a Reply

Your email address will not be published. Required fields are marked *