Using Headless Chrome to Detect XSS Vulnerabilities
What are XSS vulnerabilities?
Cross-site scripting vulnerabilities, commonly referred to as “XSS” vulnerabilities, allow a third-party attacker to run arbitrary Javascript on a website. XSS vulnerabilities might allow a website to be used for crypto mining, for example, or could allow an attacker to steal auth tokens and other sensitive information.
Most XSS vulnerabilities fall into one of two categories:
- Stored XSS vulnerabilities allow an attacker to inject malicious code directly into the vulnerable website. For example, if a site allows visitors to create and save their own content on a page — as in the case of comments on a blog post, for example — and does not take appropriate steps to sanitize that content, an attacker might inject a malicious script into their comment HTML or into an image. The script will then run each time the page loads, exposing every subsequent visitor to attack.
- Reflected XSS vulnerabilities allow an attacker to inject malicious code into a link that points to the vulnerable website — most likely because incoming requests to the website are not properly sanitized. The malicious link could be placed by the attacker on another website, in an email, etc. Reflected attacks are easier to execute, and therefore more common, than stored attacks; however, their overall impact also tends to be lower, as only users who click on the link are actually affected.
A third, less common type of vulnerability, known as a DOM-based vulnerability, allows attackers to directly modify the DOM in a victim’s browser.
What is a headless browser?
A “headless” browser is a browser that has been stripped of its graphical user interface — the functionality that most end-users interact with. The ability to manipulate the browser directly, by writing and running code, allows for much faster automated testing of websites and web applications.
Older headless browsers were third-party tools that attempted to build on top of existing browser frameworks. These days, however, most developers prefer to test with tools that are built into, and specifically designed to work with, popular browsers. In most cases, that means using Headless Chrome, which is a headless browser built into Google’s popular Chrome browser.
Using Headless Chrome to scan for XSS vulnerabilities
When performing tests on any website or web app, one of the most important things to look for is — you guessed it — XSS vulnerabilities. We can do this with Headless Chrome’s “Puppeteer” runtime, by using the page.on(‘dialog’) function to attempt to propagate an alert from any of a list of common malicious strings used in XSS attacks. Lists of common malicious strings are widely available online — GitHub is a great source.
Here’s an example that runs through a list of page URLs, testing each string on each page. Although this test routine is slow due to the double loop, it works well on a fast server:
If this test generates an alert, you’ll know that you need to take a closer look at the affected URL, and correct any sanitization issues or other dangerous loopholes.
Ideally, there would be more (open source) tools to detect XSS vulnerabilities available either by analyzing codebases themselves or via scanning/automated requests like this. There a number of automated scanners out of the box (for example: OWASP ZAP and a few tools included in the metasploit framework) but something easily understandable and extensible by the web developer community could get more developers excited about the security of their applications.
Some helpful resources:
https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.md
https://developers.google.com/web/updates/2017/04/headless-chrome
https://github.com/minimaxir/big-list-of-naughty-strings/blob/master/blns.txt