Password manager solutions are among many recommendations to keep access to your accounts secure. The idea behind a password manager is that it securely stores the credentials for many of your accounts and requires the user to only remember one password (or is configured to unlock via biometric authentication).
Password managers can have many features such as complex password generation, syncing across multiple devices, and integration into browsers as an extension. The latter allows you to conveniently log into your web accounts with only a few clicks. A browser extension that provides this functionality clearly needs to be aware of where it enters the saved user credentials. They should be entered into the validated login form and nowhere else.
Well, things aren’t always easy and sometimes odd web designs require special treatment. While evaluating the behavior of Bitwarden, a popular password manager browser extension, Flashpoint’s Vulnerability Research team noticed that embedded iframes in a web page were handled in an atypical manner. To understand why this is a problem, it’s important to have a basic understanding of what iframes are.
The inline frame element
According to the Mozilla HTML documentation the <iframe> HTML element represents a nested browsing context, embedding another HTML page into the current one.
A popular use-case is e.g. embedding map data within a web application. However, the browsing context of an iframe element is isolated from the context of the parent page or other pages from a different origin. This is defined by the Same-origin Policy which prevents arbitrary cross-domain access. It is considered a significant security concept and is implemented in all major browsers.
This isolation is critical as it prevents web pages from e.g. embedding a sensitive web resource from a different origin in an iframe and then accessing its content.
Bitwarden auto-fill behavior
As mentioned before, the way the Bitwarden browser extension handles iframes raised interest and warranted a closer look. When the Bitwarden extension determines to be on a page for which a user has saved credentials, it can offer to fill in the respective login fields. If the option ‘Auto-fill on page load‘ is enabled, it will do so without user interaction.
However, the extensions curiously also auto-fills forms that are defined in an embedded iframe even if they are from different domains.
While the embedded iframe does not have access to any content in the parent page, it can wait for input to the login form and forward the entered credentials to a remote server without further user interaction.
The Bitwarden documentation includes a warning stating that “compromised or untrusted websites” could take advantage of this to steal credentials.
There is hardly anything an extension can do to prevent stealing credentials if the website itself is compromised. However, we are aware of regular (uncompromised) websites that embed external iframes for various reasons such as advertising. This means that an attacker does not necessarily need to compromise the website itself—they just need to be in control of the iframe content.
We spot-checked a few prominent websites to see where an iframe is embedded on the login page, but the number of cases found matching this particular setup was quite low, reducing the potential risk. However, when building a Proof-of-Concept to demonstrate the vulnerability, we noticed another weakness in how the Bitwarden extension determines on which pages to enter credentials.
Bitwarden default URI matching
The default URI matching is the setting that defines how the browser extension determines to offer auto-fill logins. This is done by comparing parts of the URI of the current page with website entries in stored items in the extension’s vault. By default, it is set to ‘Base domain’, which means that the extension offers auto-fill functionality on any page where the base domain, i.e. the top-level and second-level domain, matches.
If you have encountered your fair share of web solutions and content providers, it becomes clear that this poses a problem. Some content hosting providers allow hosting arbitrary content under a subdomain of their official domain, which also serves their login page. As an example, should a company have a login page at https://logins.company.tld and allow users to serve content under https://<clientname>.company.tld, these users are able to steal credentials from the Bitwarden extensions.
Possible attack vectors
The combination of the insecure auto-fill behavior and default URI matching allows for various possible attacks to steal credentials:
- An uncompromised website embeds an external iframe (not sandboxed) that is under an attacker’s control and the ‘Auto-fill on page load’ option is enabled.
- An attacker hosts a specially crafted web page under a subdomain of e.g. a hosting provider, which has its login form under the same base domain.
In our research, we confirmed that a couple of major websites provide this exact environment. If a user with a Bitwarden browser extension visits a specially crafted page hosted in these web services, an attacker is able to steal the credentials stored for the respective domain.
As mentioned before, if the ‘Auto-fill on page load’ option is enabled, no further user interaction is required. However, we confirmed that if the user fills a login form via the context menu, forms embedded in iframes are filled as well.
A curious vendor response
We contacted Bitwarden to attempt a coordinated disclosure. To our surprise, the vendor appeared to be well aware of this issue. We received a response with a link to a Security Assessment Report that was dated November 8, 2018, which describes the vulnerability regarding iframe handling (BWN-01-001). Since “users should be able to log into services where embedded iframes from another domain are present”, the issue remained unfixed. This means that this vulnerability can be considered documented and public for well over four years!
Considering the importance of compromised credentials as the initial stage for attackers to gain access, we believe the vendor’s assessment from 2018 to be invalid. In hopes of encouraging Bitwarden to review their conclusion, we created and provided two examples that demonstrate how this can be exploited. We also clarified why the described use-case should be re-evaluated considering the demonstrated attacks that were not part of the initial report. One example was a generic proof-of-concept, the other a working exploit in a prominent hosting environment that allows attackers to disclose the account credentials and in turn grants access to all of the services on that platform.
In response, Bitwarden provided a use-case on why iframes need to be handled in this particular way. However, they plan to exclude the reported hosting environment from the auto-fill functionality but do not plan to change the general iframe functionality. This means that the root cause has not been addressed but simply one attack vector. Briefly researching similar service providers indicates that this vulnerability is highly likely to be exploitable on different platforms. The prioritization of their use-case over security and response to our report is concerning and organizations should be aware of the security concerns in the product. It should also be noted that a brief evaluation of other password manager extensions shows that none of those will auto-fill iframes from different origins or show warnings for iframes from different origins. This currently appears to be unique to Bitwarden’s product.
Remediate vulnerabilities with Flashpoint
Sign up for a free trial today to get visibility into this issue, as well as the other 97,000 vulnerabilities not found in CVE and NVD.
VulnDB customers can read more about this vulnerability in VulnDB ID 313593. We encourage anyone using the vulnerable extension to disable the ‘Auto-fill on page load’ functionality and configure the ‘Default URI match detection’ setting to ‘Host’ or ‘Exact’. This mitigates exploitation via subdomains on hosting providers. It should be noted that it does not prevent credential disclosure in case a web application embeds potentially attacker-controlled iframes in a login page.