XSS in Google Gruyere
This next part takes place on Google Gruyere, an XSS laboratory operated by Google that explains different aspects of XSS alongside appropriately vulnerable form input:
Google Gruyere is based loosely on a social network, such as Instagram or Twitter, where different users can share public snippets just like the former site's 280-word text blocks. Beyond the obvious, advertising of the service as being susceptible to XSS, there are small pieces of text, similar to what you'd find in real applications, hinting at areas of vulnerability. Some or limited support of HTML in a specific form is always a chance that the filters put in place by the site's developers to allow formatting markup, such as <p></p>, <b></b>, and <br/>, while keeping out scary stuff, such as <script></script>, will fail to sanitize your specially-crafted snippet.
Going through the submission form to create a New Snippet (after setting up an account), we can try to probe at the outer edges of the sanitizing process. Let's try using a script that even the most naive filter should capture:
<script>alert(1)</script>
A plain script tag, without any obfuscation, escape characters, or exotic attributes, is a pretty slow pitch, as follows:
When we look at the result of the submission, no alert() window is displayed and there's nothing to else to trigger the execution of the code, as follows:
The filter undoubtedly has some holes in it, but it does function at the most basic level by stripping out the <script> tags. Going through the XSS snippet lists we have in our Seclists repository, we find another one to try, ensuring the HTML tag is likely to be included in a form input meant to allow formatting code:
<a onmouseover="alert(document.cookie)">xxs link</a>
document.cookie is a glimpse of our proposed attack scenario and a simple piece of data to surface via alert():
Going through the submission process again, we receive a different response. Success! Our strategy, using a boring formatting tag to Trojan-horse a malicious payload contained in its attribute, worked, and we now have a confirmed vulnerability to report: