XSS-Auditor — the protector of unprotected
Quick introduction:
The XSS-Auditor is a tool implemented by various browsers whose intention is to detect any reflected XSS (Cross-site scripting) vectors and block/filter each of them.
The XSS Auditor runs during the HTML parsing phase and attempts to find reflections from the request to the response body. It does not attempt to mitigate Stored or DOM-based XSS attacks.
If a possible reflection has been found, Chrome may ignore (neuter) the specific script, or it may block the page from loading with an ERR_BLOCKED_BY_XSS_AUDITOR error page.
The original design http://www.collinjackson.com/research/xssauditor.pdf is the best place to start. The current rules are an evolved response to things observed in the wild.
Abusing the block mode
When the XSS-Auditor is being run in block mode, any attempt of reflected XSS will be blocked by the browser. Recent research led to abuse of that behavior by providing a fake reflected XSS vector allowing exfiltration of information. The technique exfiltrating such information is known as XS-Search (Cross-Site Search) attack, which is getting more and more popular these days. (https://portswigger.net/daily-swig/new-xs-leak-techniques-reveal-fresh-ways-to-expose-user-information)
Some researchers demonstrated how serious the issue is basing on real-life scenarios. I won’t be divagating about the issue in this article but I will include the research that will help you understand the issue from the root.
- Abusing Chrome’s XSS auditor to steal tokens (2015) — by @garethheyes
- XS-Search abusing the Chrome XSS Auditor (2019) — Follow-up of a solution of the filemanager task from 35c3 ctf by LiveOverflow
- Google Books X-Hacking (2019) — Bug Bounty report reported by me @terjanq
The fix
To prevent the mentioned XS-Search, the Chromium team decided to revert the default behavior of the XS-Auditor from block to filter mode which came live in the recent Google Chrome version (v74.0.3729.108) that was released just a couple of hours prior to this publication.
https://chromium-review.googlesource.com/c/chromium/src/+/1417872
That, however, opens new and more dangerous ways to exploit that feature.
Let’s XSS
With the “fix” it’s now possible to filter unwanted parts of the code and maybe perform an XSS on vulnerable websites that haven’t set a X-XSS-Protection: 1; mode=block
or X-XSS-Protection: 0
HTTP headers.
I will demonstrate the attack basing on the write-up to the DOM Validator challenge from the latest ångstrom 2019 CTF.
Abusing the filter mode — write-up
In the challenge, we were provided with two functionalities: creating a post and reporting URLs to the admin.
Upon creating a post a new file on the server was created with the name <title>.html
and the post body inserted into the file. User’s payload was inserted into <p>USER_PAYLOAD</p>
inside the <body>
.
In the example above the user’s payload was <script>alert('pwned')</script>
. However, the inserted script won’t be executed because of the DOMValidator.js
file, which looks like:
The script calculates some sort of the hash of the document and if it doesn’t match the original hash the whole document will be removed and hence the inserted scripts not executed.
The first thing I tested was to look into admin’s headers when visiting my website:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/74.0.3723.0 Safari/537.36
. I noticed that admin is using an unstable version of Google Chrome (unstable at the time) and I knew that it’s the version when XSS-Auditor went from block to filter mode by default. Since the website didn’t set a X-XSS-Protection
header I already knew what an unintended solution will be ;)
It’s not possible to filter out the DOMValidator.js
script because it’s loaded from the same domain, but it’s possible to filter out the sha512.js
one. It is done by simply appending the xss=<script src=”https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/sha512.js">
parameter into the URL.
The above filtering will cause the crash of the DOMValidator.js
script, because it uses CryptoJS.SHA512()
function, and hence the inserted script will be successfully executed.
So by sending that URL to the admin, I was able to obtain their cookies where also the flag was included.
Conclusion
As for the conclusion, instead of the XS-Search, the XSS could be performed on websites that wouldn’t be vulnerable otherwise due to the recent revert change.
Given that, the obvious questions arise: Is the change worth the risks? Should the Chromium team follow the Microsoft and disable the Auditor already? (https://portswigger.net/daily-swig/xss-protection-disappears-from-microsoft-edge)
I encourage you to join the discussion under the tweet: https://twitter.com/terjanq/status/1121412910411059200
Update
From https://www.chromium.org/developers/design-documents/xss-auditor we can read that XSS Auditor was fully removed in Chrome 78!
The feature was permanently disabled on 5-August-2019 and shortly after fully removed for Chrome 78.
But also the discussion around the issue was made public https://bugs.chromium.org/p/chromium/issues/detail?id=922829, which proved the issue to be hard to fix.