This blog will demonstrate how a hacker could harvest credentials of the main application of an organization by taking advantage of the autofill features implemented in modern browsers and password manager tools and bypassing the CSP restrictions.
Overall Structure of the Organization
The organization has two main applications, the first one https://control.example.org, which is the main application acting as a central dashboard for its customers. One feature under this application allows its customers to upload sanitized HTML files as a template into a S3 bucket . The S3 bucket is behind AWS CloudFront and the CloudFront is CNAME to cdn.example.org for performance and scalability reasons.
The following diagrams illustrate how these two applications work.
XSS exploitation is not possible due to sanitization and CSP header
As the application allows users supplied HTML template through the control panel https://control.example.org and then render it under the https://cdn.exampe.com/my_user_id/template1, the first thought was to check whether XSS is possible. However, after spending some time on discovering potential XSS vulnerabilities and exploiting them, it turns out this method did not work as expected due to the following implementation to prevent XSS exploitation.
User input Sanitization Implemented under control.example.org
The user input sanitization seems to be very robust after numerous with different payloads. It seems that only these DOM elements <div >,<form>, <input>,<image> and <a> are allowed to be added in the user’s supplied HTML template whereas all the event handlers are filtered out.
The following template seems to be able to pass the sanitization method and is able to be stored and rendered under the browser when opening https://cdn.exampe.com/{user_id}/template1
However, the Content-Security-Policy header implemented under cdn.example.org is blocking the execution of these JavaScripts.
Strict Content-Security-Policy is present under cdn.example.org
The cdn.example.org where users supplied HTML template has the below Content-Security-Policy added by AWS Lambda@Edge in order to prevent potential XSS exploitation
Since the Content-Security-Policy does not allow inline JavaScript when rendering the page under a modern browser, the template containing inline JavaScript uploaded could not be used to launch XSS exploitation.
Even though launching XSS exploitation seems not feasible at this moment due to the restrictions, we could explore other potential exploitation methods.
Take advantage of autofill feature to steal user credentials
Most modern browsers and password managers have Autofill features enabled by default to bring a faster sign in, billing information and other user experiences. It means, the browser or password managers will save these user inputs and populate them and autofill them next time for you.
The feature is convenient but with a tradeoff for security. There are a couple of cavities in the feature. One big problem is that the Autofill feature will pull saved credentials from its sibling subdomains and autofill them into forms located under other subdomains.
For example, users login to the https://control.example.org and click Save passwords pop ups in the browser during login. The saved username/password will be pulled from the browsers and autofill into the Login form again next time when users open the login page under https://control.example.org.
Now, users created a similar Login Form (same names for the input fields) on a sibling subdomain https://cdn.example.org, the browser will pull the save password for control.example.com and autofill it under the Login form under https://cdn.example.org. That sounds quite scary if an attacker could control another subdomain or is able to manipulate some pages in the subdomains.
From an attacker’s perspective, once the username and password are auto filled into a Login Form they control, they could steal these credentials by modifying the action attribute in the Login form to receive the credentials once users click the Signin button if auto submit is not enabled.
You make it an even converter by applying a Clickjacking exploiting where your trigger user clicks the Signin button.
Conclusion
Autofill feature provided by password managers and browsers is a convenient feature with security tradeoff. Especially, when your website has potential XSS vulnerabilities or there are many subdomains under your organization, you need to pay extra attention to manage the subdomains. For end users, if possible you could turn off autofill password features to prevent password stealing.
A Study of CSP Headers employed in Alexa Top 100 Websites
Introduction
The Content Security Policy (CSP) is a security mechanism web applications can use to reduce the risk of attacks, such as XSS, code injection or clickjacking, by informing the browser that something should be blocked when loading or parsing the HTML content. The CSP header has become a standard metric to improve the security posture of modern applications as most application security tools would likely flag a security issue in your applications if it detects the absence of the CSP headers.
Recently I was tasked to add a CSP header to one of our applications to ensure it is fully equipped to combat some potential XSS issues. After spending a while investigating which CSP policies would be a good candidate to use, I found it is not an easy task to implement a thorough CSP header while avoiding breaking legitimate site functionality. Then I decided to check how other popular web applications are utilizing CSP headers and how I could learn from them to build a robust CSP header.
How Alexa Top 100 websites are adopting CSP header
I started to evaluate How Alexa Top 100 websites are adopting CSP header to harden its security posture by checking whether these websites are adding CSP headers and analyzing whether these CSP headers are really useful to protect against some common attacks, such as XSS and Clickjacking. When analyzing the CSP headers in these top websites, I was using Google CSP Evaluator to check how each CSP directives are defined in the CSP headers besides manual testing. The result is kind of bittersweet as there are some unexpected behaviors and implementations of CSP headers on these top websites. Below are some findings worthy to be mentioned
Findings
Finding 1: 51 out of Alexa Top 100 websites have CSP header added
Though I was expecting that every website in Alexa Top 100 websites should have CSP header implemented by considering these websites attract millions of users on a daily basis, it turns out only 51 websites out of Alexa Top 100 have CSP headers enabled in the web application.
Right, more than 50% of the websites are at least using CSP headers (some of them are use Content-Security-Policy-Report-Only), that is not that bad comparing to the statistics, less than 4% of URLs are carrying CSP headers by referring to a Google Research works.
But if you get a closer look at the CSP headers employed in these 51 websites, some of them are only used to protect against Clickjacking attacks, some of them are using the CSP header as Report-Only mode. The worst part is that most of these CSP headers are not implemented correctly to mitigate potential attacks due to misconfiguration.
Finding 2: More than half of the websites are suffering from common CSP misconfiguration
Misconfiguration 1: ’unsafe-inline’ keyword without specifying a nonce defined in script-scr directives
According to Google research ‘unsafe-inline’ within script-src directive is the most common security misconfiguration for Content Security Policy (CSP) and 87.6% CSP employed the ’unsafe-inline’ keyword without specifying a nonce, which essentially disables the protective capabilities of CSP against XSS exploitation.
There are 34 websites where ‘unsafe-line’ is specified under script-src directive in the CSP configuration. Whereas, 18 out of these 34 websites (roughly 50%) are using the ‘unsafe-inline’ keyworks without specifying a nonce or a hash, which means the CSP header is not configured in a correct way to mitigate XSS exploitation.
This finding is really astonishing as it means around 50% of these 34 heavily visited websites (including facebook, ebay, shopify) are not configuring CSP header in a correct way. Following is a snapshot where ‘unsafe-inline’ is specified without a nonce in the a CSP header employed by one of the Alexa Top 100.
Misconfiguration 2: data: URI schema is allowed in some directives
While around 50% of CSP employed the ‘unsafe-line’ keyword without specifying a nonce, there is another misconfiguration scenario where data: URI scheme is allowed for script-src, frame-src, object-src directive, this misconfigure also defeats the XSS protection of CSP header.
Around 25% of CSP headers employed by the Alexa Top 100 websites are using data:uri under its script-src, frame-src or object-src directives (or default-scr directive when script-src directive is missing). For example, the following XSS attack is utilizing data:uri schema to pass malicious javascript code under your application
Misconfiguration 3: object-src directive allows * as source or is missing (no fallback due to absence of default-src)
In some CSP headers employed by the Alexa Top 100, * (wildcard) is used in object-src directive or default-src directives, which significantly reduce the protection of CSP header as there are multiple ways to inject malicious javascript code when * is used for these directives.
The following CSP header is extracted from one of website
These misconfigurations do not mean the CSP header is not effective at all though these misconfiguration makes CSP protection weak, even useless in some cases.
Finding 3: Some minor issues are ignore in the CSP headers
Ignored issue 1: unsafe-inline are widely added without nonce for style-src directive
Most security engineers downplay the potential security risks imposed by inline style, which is perfectly proved by the data we collected by reviewing CSP header in Alexa Top 100 websites. Among the CSP headers employed by these websites, much more CSP headers are allowing inline style compared to allowing inline script
NO. of websites using unsafe-inline keyword without nonce under script-src directive
16
NO. of websites using unsafe-inline keyword without nonce under style-src directive
22
Though allowing inline style is not as bad as allowing inline script without a nonce, inline style could open the door for a number of attacks like injecting a css keylogger to steal sensitive data. It means, it still makes some sense to add nonce under style-src directive to prevent potential attack by using inline style
Ignored Issue 2: No Access Control or throttling method added to the report-uri endpoint to preventing malicious user from abusing it
The ‘report-uri’ is a very powerful feature built into CSP that allows website adminstrator to gain insight on their deployed policy by instructing the user agent to report attempts of violating the CSP to the report uri endpoint . You can enable CSP’s reporting feature by specifying the URL of your reporting endpoint with a report-uri directive in your policy. Take the CSP header employed by instragram.com for example, all the violation of CSP policy will be reported to https://www.instagram.com/security/csp_report/
There are many benefits of enabling a report-uri directive for CSP as the CSP violation report might indicate some attempts to bypass or violate your CSP policy to exploit some vulnerability. But this feature also introduces some concerns due to the way how the report-uri endpoint is implemented.
One concern is that any users could send massive invalid CSP violation reports to the report-uri endpoint as most of these report-uri endpoints have no access control or throttle method to prevent this kind of attack. Due to the massive invalid CSP violation, it may make it really harder to spot legitimate attempts to violate CSP policy. In some scenarios, if the report-uri endpoint is not scalable and a high volume of invalid CSP violation report could cause DOS of the endpoint.
CSP itself is a very rich feature as it has a dozen of directives that a user could specify. I am pretty sure that you would spot some other funky or interesting implementations of CSP implementations under the Alexa Top 100 websites. Besides that, to define a robust CSP policy without breaking the applications is not that easy. For example, some disallowing inline script CSP policy could break desired features of jQuery. That could explain why these top tier websites.
Conclusion
While CSP could be very helpful as a part of a defense-in-depth strategy, your application should not completely rely on the protection of CSP headers as a sole defensive mechanism as misconfigurations could make the protection being bypassed easily. The CSP data collected from the Alexa Top 100 is just a tip of the iceberg. I believe there are much more misconfigurations in the wild.
Applying a DAST tool or SAST tool to find potential vulnerabilities, for example, XSS and Clickjacking, and eliminate them is the most efficient solution as CSP header does not eliminate the security flaws but make the exploitation hard.