In this article, we will share a Content Security Policy (CSP) bypass vulnerability in Microsoft Edge. The bypass was done by abusing the browser’s XSS filter.
Both XSS filter and CSP are designed to protect users from XSS attacks, however this vulnerability allows attackers to abuse one XSS protection mechanism in order to bypass another.
XSS filter was first introduced in Internet Explorer 8. The intent of a XSS filter is to mitigate reflective XSS attacks. The XSS filter of IE/Edge works in the following way: when a browser loads a URL, the XSS filter checks if some parameters of the URL may contain XSS payloads, using a set of predefined regular expressions. For example,
http://example.com/index.php?id=100is clearly harmless, but for a URL like
http://example.com/index.php?id=<script>alert(1)</script>, the value of parameter
id may be a XSS payload. Therefore, to determine whether it is a reflective XSS attack IE/Edge checks if the returned HTML contains the substring
<script>alert(1)</script>. If it does contain it IE/Edge assumes it is reflected from the
Notice how this assumption may not be true: what if
<script>alert(1)</script> is hardcoded in the page and the
id parameter actually does not have any effect?
There are two modes for XSS filter: default mode and the block mode. Sites can enable the block mode by setting an HTTP header: X-XSS-Protection: 1; mode=block”. In the block mode IE/Edge block the entire HTML from rendering. In default mode IE/Edge try to vanquish XSS payloads by modifying the corresponding HTML tags. i.e if Edge assumes
<script>alert(1)</script> is a XSS, it changes this element to
<sc#ipt>alert(1)</script>. Thus, the DOM parser will not parse this segment as a <script> element, so it won’t execute.
Now let us see the vulnerability known as CVE-2017–0135. There are two ways for a site to set a Content Security Policy: via Content-Security-Policy HTTP response header field or via the <meta> tag. An example of such a meta element is as follows:
<meta http-equiv=”Content-Security-Policy” content=”script-src ‘self’”>. Now suppose here is the HTML for URL http://example.com/xss.html:
<meta http-equiv=”Content-Security-Policy” content=”script-src ‘self’”>
The CSP should block
alert(document.domain)from executing. To bypass the Content Security Policy let us ask users to visit
http://example.com/xss.html?<meta http-equiv=”Content-Security-Policy” content=”script-src ‘self’”>
By default Edge’s XSS filter simply modifies the meta tag to
<me#a http-equiv=”Content-Security-Policy” content=”script-src ‘self’”>, which then kills the Content Security Policy and the alert is executed.
It is fixed by blocking the entire HTML page when the XSS filter detects the query string matches any meta element regardless of the modes.
Although this vulnerability has in fact been fixed it is still a good idea to set “X-XSS-Protection: 1; mode=block”. Also, it should be known Content Security Policy policies delivered via HTTP headers are not vulnerable to this bypass attack.