Chrome switching the XSSAuditor to filter mode re-enables old attack

Recently, Google Chrome changed the default mode for their Cross-Site Scripting filter XSSAuditor from block to filter. This means that instead of blocking the page load completely, XSSAuditor will now continue rendering the page but modify the bits that have been detected as an XSS issue.

In this blog post, I will argue that the filter mode is a dangerous approach by re-stating the arguments from the whitepaper titled X-Frame-Options: All about Clickjacking? that I co-authored with Mario Heiderich in 2013.

After that, I will elaborate XSSAuditor's other shortocmings and revisit the history of back-and-forth in its default settings. In the end, I hope to convince you that XSSAuditor's contribution is not just neglegible but really negative and should therefore be removed completely.


JavaScript à la Carte

When you allow websites to frame you, you basically give them full permission to decide, what part of JavaScript of your very own script can be executed and what cannot. That sounds crazy right? So, let’s say you have three script blocks on your website. The website that frames you doesn’t mind two of them - but really hates the third one. maybe a framebuster, maybe some other script relevant for security purposes. So the website that frames you just turns that one script block off - and leave the other two intact. Now how does that work?

Well, it’s easy. All the framing website is doing, is using the browser’s XSS filter to selectively kill JavaScript on your page. This has been working in IE some years ago but doesn’t anymore - but it still works perfectly fine in Chrome. Let’s have a look at an annotated code example.

Here is the evil website, framing your website on example.com and sending something that looks like an attempt to XSS you! Only that you don’t have any XSS bugs. The injection is fake - and resembles a part of the JavaScript that you actually use on your site:

<iframe src="//example.com/index.php?code=%3Cscript%20src=%22/js/security-libraries.js%22%3E%3C/script%3E"></iframe>

Now we have your website. The content of the code parameter above is part of your website anyway - no injection here, just a match between URL and site content:

<!doctype html>
<h1>HELLO</h1>
<script src="/js/security-libraries.js"></script>
<script>
// assumes that the libraries are included
</script>

The effect is compelling. The load of the security libraries will be blocked by Chrome’s XSS Auditor, violating the assumption in the following script block, which will run as usual.

Existing and Future Countermeasures

So, as we see defaulting to filter was a bad decision and it can be overriden with the X-XSS-Protection: 1; mode=block header. You could also disallow websites from putting you in an iframe with X-Frame-Options: DENY, but it still leaves an attack vector as your websites could be opened as a top-level window. (The Cross-Origin-Opener-Policy will help, but does not yet ship in any major browser). Surely, Chrome might fix that one bug and stop exposing onerror from internal error pages . But that's not enough.

Other shortcomings of the XSSAuditor

XSSAuditor has numerous problems in detecting XSS. In fact, there are so many that the Chrome Security Team does not treat bypasses as security bugs in Chromium. For example, the XSSAuditor scans parameters individually and thus allows for easy bypasses on pages that have multiple injections points, as an attacker can just split their payload in half. Furthermore, XSSAuditor is only relevant for reflected XSS vulnerabilities. It is completely useless for other XSS vulnerabilities like persistent XSS, Mutation XSS (mXSS) or DOM XSS. DOM XSS has become more prevalent with the rise of JavaScript libraries and frameworks such as jQuery or AngularJS. In fact, a 2017 research paper about exploiting DOM XSS through so-called script gadgets discovered that XSSAuditor is easily bypassed in 13 out of 16 tested JS frameworks

History of XSSAuditor defaults

Here's a rough timeline

Conclusion

Taking all things into considerations, I'd highly suggest removing the XSSAuditor from Chrome completely. In fact, Microsoft has announced they'd remove the XSS filter from Edge last year. Unfortunately, a suggestion to retire XSSAuditor initiated by the Google Security Team was eventually dismissed by the Chrome Security Team.

This blog post does not represent the position of my employer.
Thanks to Mario Heiderich for providing valuable feedback: Supporting arguments and useful links are his. Mistakes are all mine.

Other posts

  1. Chrome switching the XSSAuditor to filter mode re-enables old attack
  2. Challenge Write-up: Subresource Integrity in Service Workers
  3. Finding the SqueezeBox Radio Default SSH Passwort
  4. New CSP directive to make Subresource Integrity mandatory (`require-sri-for`)
  5. Firefox OS apps and beyond
  6. Teacher's Pinboard Write-up
  7. A CDN that can not XSS you: Using Subresource Integrity
  8. The Twitter Gazebo
  9. German Firefox 1.0 ad (OCR)
  10. My thoughts on Tor appliances
  11. Subresource Integrity
  12. Revoke App Permissions on Firefox OS
  13. (Self) XSS at Mozilla's internal Phonebook
  14. Tales of Python's Encoding
  15. On the X-Frame-Options Security Header
  16. html2dom
  17. Security Review: HTML sanitizer in Thunderbird
  18. Week 29 2013
  19. The First Post