Two important headers that can mitigate XSS are:
So what is the difference?
Details are here, but basically the four supported options are:
X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; report=<reporting-uri>
It should be noted that the auditor is active by default, unless the user (or their administrator) has disabled it.
will turn it back on for the user.
What I wanted to show you was the difference between specifying
block, and either not including the header at all (which therefore will take on the setting in the browser) or specifying
block. Also, for good measure I will show you the Content Security Policy mitigation for cross-site scripting.
I will show you a way that if a site has specified
block, how this can be abused.
The linked page has the following code in it:
<script>document.write("one potato")</script><br />
<script>document.write("two potato")</script><br />
Now if we link straight there from the current page you’re reading, the two script blocks should fire:
?xss1=<script>document.write("one potato")</script>&xss2=<script>document.write("two potato")</script>
Note that the following will not work from Firefox, as at the time of writing Firefox doesn’t include any XSS auditor and therefore is very open to reflected XSS should the visited site be vulnerable. There is the add-on noscript that you can use to protect yourself, should Firefox be your browser of choice. Note the following has been tested in Chrome 64 only. I will also enable your XSS filter in supported browsers by adding
X-XSS-Protection: 1 to the output.
Note how the browser now thinks that the two script blocks have been injected, and therefore blocks them and only outputs the plain HTML. View source to see the code if you don’t believe it is still there.
Viewing F12 developer tools shows us the auditor has done its stuff:
Viewing source shows us which script has been blocked in red:
Viewing the source shows the attacker has just blocked what they wanted by specifying the source code in the URl:
Of course, editing their own link is fruitless, they would have to be passing the link onto their victim(s) in some way by sending it to via email, Facebook, Skype, etc …
What are the risks in this? Well The Web Application Hacker’s Handbook puts it better than I could:
So, how can we defend against this? Well, you guessed it, the
X-XSS-Protection: 1; mode=block
So let’s try this again with that specified:
So by specifying
block we can prevent an attacker from crafting links that neutralise our existing script!
Content Security Policy then?
Just to demo the difference, if we output a CSP header that prevents inline script and don’t attempt to inject anything:
Chrome shows us this is solely down to Content Security Policy:
To get round this as site developers we can either specify the SHA-256 hash as described in our CSP, or simply move our code to a separate
.js file as long as we white-list
self in our policy. Any attacker injecting inline script will be foiled. Of course the problem with Content Security Policy is that it still seems to be an after-thought and trying to come up with a policy that fits an existing site is very hard unless your site is pretty much static. However, it is a great mitigation if done properly. Any weaknesses in the policy though may be ripe for exploitation. Hopefully I’ll have a post on that in the future if I come across it in any engagements.
*Yeh yeh, you’re not using X-XSS-Protection for evil, but lack of
block of course, and if no-one has messed with the browser settings it is as though
X-XSS-Protection: 1 has been output.