Linting For Bugs & Vulnerabilities

A couple of days ago my colleague Lawrence shared with me an excellent presentation delivered by Lewis Ardern at OWASP San Francisco. In it he discusses reviewing modern JavaScript applications and dedicates around a ¼ of the presentation to a tool called ESLint, which can be used to perform static analysis on JavaScript.

I’ve spent the last few days figuring out how it all works and building a set of custom JavaScript analysis rules by combining multiple open source projects. I’ve written this post to help make the journey more streamlined for anyone else wanting to jump in with static JavaScript analysis while on a penetration test or bug bounty hunting.

So, what is Linting:

However, a number of (awesome) developers have written a number of plugins for the popular JavaScript Linter, ESLint, which enable it to scan for JavaScript security issues.

Now if you come from a web developer background, you may already be intrigued. But if you don’t, what this can do is help you find DOM issues, like XSS & Arbitrary Redirects.

So first we need to set up a few things. You need to install npm, eslint and a number of other libraries and security plugins.

Since I’m on OSX I’ll be using brew, but if you have another operating system, check out the npm download page(https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) for instructions.

brew install npm
npm i -g eslint eslint-plugin-standard eslint-plugin-import eslint-plugin-node eslint-plugin-promise eslint-config-standard eslint-config-semistandard eslint-plugin-scanjs-rules eslint-plugin-no-unsanitized eslint-plugin-prototype-pollution-security-rules eslint-plugin-angularjs-security-rules eslint-plugin-react eslint-plugin-security eslint-plugin-no-wildcard-postmessage

Next download my custom config files which configure which issues ESLint will report on:
git clone https://github.com/Greenwolf/eslint-security-scanner-configs

Note: This project combines & uses code from a number of fantastic open source projects. Thank you to the original authors:
·
Lewis Arden
·
Mozfreddyb
·
Mozilla
·
Nodesecurity
·
Yannickcr

Now our installation is complete, to perform static JavaScript analysis, what we need is some actual JavaScript! Please be mindful this was from a live test so some of the images will be heavily redacted.

We can gather all the Javascript from an entire site that has been spidered and combine it into one file with Burp. In the Target Site map menu, Right click on the site, Engagement tools, Find scripts:

Use ctrl-a to select every script, then Export scripts in the top right. This brings up an export window where we can rename our file and remove duplicates.

However, this leaves us with over 3MB of disgustingly formatted JavaScript.

So, let’s make our lives a little easier. All these huge blocks of minified code are public libraries, which have already been audited and reviewed many times. So, let’s just get rid of them.

We spend 5 minutes going through the script deleting long lines over 200 characters and the huge blocks of minified code. This leaves us with only the custom JavaScript that the developers have written for the application. It gets us down from ~3800 lines at 3mb to only 253 lines at 9kb!

This is much more manageable. However, going through 250 lines of JavaScript that might not have any security issues still doesn’t sound appealing. So, let’s use ESLint to see if there is anything worth investigating!

We need to turn this into a project first, so move your JavaScript into a new folder and run:
npm init

Press enter multiple times to choose default for everything and it will create a file called package.json.

Next we run eslint using the custom configuration files you downloaded earlier. There are 2 versions, a light and a heavy scan. The heavy one flags more issues but contains more false positives. I always start with the light scan.

Nice, we have some results. We start looking through the file and see that the first few are false positives. But then:

A DOM XSS flagged because of an unsafe assignment to innerHTML on line 170 & 174:

Followed by a DOM Arbitrary Redirect flagged because assignments to location can be unsafe on line 185:

Now both of these are quite impractical attacks as they are based on cookie values and wouldn’t even get you a bug bounty payment (P5 😭). However, I just wanted to demonstrate some of the issues that static analysis techniques can help you find, on real-world code, not an intentionally vulnerable project. Even if they were quite trivial.

I hope you enjoyed this getting started with security linting blogpost, and it encourages you to try some new tools and techniques. If you have any questions or comments, please feel free to leave a response below!