Every DevSecOps engineer will recommend you to start using security tests. I personally just blogged about it recently – if you’re not familiar with the concept, I’ll highly encourage you to read it first. It’s sound right, but there is one important question: Can we find real exploits using security tests? Can we pwn a web application by scanning it for security issues?
The best way to find out is to take a real broken web application, scan it with various security tests and look for exploits we can use. Today victim is OWASP Juice Shop, a very famous vulnerable web application, written using NodeJS and Angular. Let’s try to hack it, the DevSecOps way!
docker run -it -p 9090:9090 opensecurity/nodejsscan:latest
Now I can access NodeJsScan by opening http://localhost:9090 in my browser:
Very intuitive: all I need to do is create a zip file containing Juice Shop source code and upload it. After the scan completes, I can see the report with all the findings:
Not surprisingly, there are a few issues reported. I want to focus on one specific issue – the SQL injection. SQL Injection is an attack that let the attacker run arbitrary SQL code on the database. Let’s see what information I can get from NodeJsScan about this issue:
This is very informative – I can see that the SQL injection is in the login component. By looking on the code, I can see that the user email passed from the request is passed without sanitization to the query. Now that I have all this information, it’s time to exploit it:
Notice the weird email (
' or 1=1--)? This is the attack – injecting malicious SQL command, which let me impersonate other users. Using this “email” and any password should let you log in as administrator (which is the first user in the database). Great job NodeJsScan!
The second method I’m going to use is dynamic analysis. For dynamic analysis, the best option is to use OWASP Zap, a free OSS security tool. When Zap is used as a proxy, it can inspect the requests and responses, and look for various security issues. So all I need to do is (a) proxy my browser through Zap and (b) browse through all the pages in Juice Shop. This is a boring and time-consuming task, so I prefer to automate it.
Juice Shop has a great tests coverage, including an end to end test. The end to end tests is using selenium to emulate user interactions with all the different features of Juice Shop – which is exactly what I need. All I need to do is proxy these tests with Zap – and I have a dynamic analysis scan. Achieving that required a really small change (see my PR for details), and now all that is required is running (Assuming that Zap is running and that
http://localhost:8080 is Zap’s proxy address.):
http_proxy=http://localhost:8080 yarn run e2e
After the end to end test completed, we can take a look at Zap’s alerts to look for interesting findings:
Zap detected an Open Redirect issue. This means that the app will accept any URL and will redirect the user to this URL. Really handy when a hacker wants to launch a phishing attack, for example. To exploit this attack, all we need to do is to send the following URL to the targeted user:
See how the URL looks like a regular juice shop URL? the user visiting this URL will be redirected to evil.com, thinking they visiting Juice Shop. Nice! Also, notice how I had to add
source=https://github.com/bkimminich/juice-shop to my URL? The developers try to mitigate this attack, by checking the target URL but failed to do so properly. Always check your mitigations thoroughly!
The last method will be to scan all the packages used by Juice Shop. As you might already know, each package you’re using might contain known security issues (see A9 on OWASP Top 10 for more details). The only way to find out (besides waiting for hackers to exploit these vulnerabilities) is to scan the packages you’re using against a database of packages with known vulnerabilities continuously.
This might sound complicated, but it’s actually very simple. Since NPM 6, NPM has built-in command,
npm audit, that scan the all the packages in the current project (follow this guide for more details). NPM audit is a great solution for this issue, but it is not perfect. The tricky part here is maintaining a database of all the packages with known security issues. This is why NPM audit is a great solution, but not enough. For this reason, but not only, I like to use Snyk, a commercial service for packages scanning ([here](https://snyk.io/blog/whats-a-known-vulnerability) you can read more to find out why Snyk has a better database). To scan Juice Shop packages with Snyk all we need to do is run the following command:
This will guide Snyk to test all the packages in the current folder. When the scan completes, the tool will list all the issues found by Snyk:
Well, this is impressive. Juice Shop include 16 packages with known vulnerabilities, pretty impressive. Let’s pick one of the issues and inspect it:
This is an issue in sanitize-html package (full details here). As the name implies, this is a package that should sanitize user input and protect the website from a malicious payload. A good developer used this packages to mitigate XSS attacks. This is great, but what happens when the library used to protect from XSS has bugs? Yep, you get an XSS attack. Here is an example malicious payload:
See the nested iframe tag, inside another script tag? This is the bug. Sanitize-html will sanitize the first script, but not the second one. Let’s see it in action:
I started this post by asking “do security tests can find real exploits”. The answer now is a clear yes. Security tests can find real exploits. If the developers of Juice Shop were using one of the tools described here, they had much fewer security issues.
What about you? What security issues exist in the app you’re working on? Now it’s time to scan it with one of the tools mentioned here and find out (this [post](https://www.omerlh.info/2018/10/04/write-good-code-with-security-tests/) can help you get started).