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
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):
- The attacker injects a form with a username and password field into the vulnerability document.
- The password manager detects the form and automatically (as discussed above) inserts the credentials into the fields.
- 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.
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:
- 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.
- 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.
- 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.
- 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.
- 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|
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
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.
- 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.