After completing my OSCP in November, I decided it was time to round my skills out a bit, maybe even get some experience with the defensive side of things. As such, I decided to complete both the Security Engineer and DevSecOps paths on TryHackMe before diving in for some self-driven studying. After that, I like to check out some FOSS tools and see if I can get my hands dirty. For this writeup, I’ll be talking about OWASP Dependency Check.
Per their website:
Dependency-Check is a Software Composition Analysis (SCA) tool that attempts to detect publicly disclosed vulnerabilities contained within a project’s dependencies. It does this by determining if there is a Common Platform Enumeration (CPE) identifier for a given dependency. If found, it will generate a report linking to the associated CVE entries.
Essentially this means, that the tool checks source code for any known vulnerabilities in the packages being used. It doesn’t necessarily check for what the application might do, and it doesn’t scan for any vulnerabilities that might come up when the application actually runs. Furthermore, it can only discover public vulnerabilities as it relies on existing databases such as NIST’s National Vulnerability Database (NVD), so it can’t alert the user to zero-days or anything like that.
Note that because the scanner uses an existing database to check code against, you must either download the full database (not small) or use an API key. If you wish to use an API key, you can request one here.
That being said, it seems like a good place to start because it should find any low hanging fruit.
The first step of course is to download the application. I was a little surprised it wasn’t available through APT, but no worries. You can download the latest release from the GitHub page here. You can also run wget https://github.com/jeremylong/DependencyCheck/releases/download/v8.4.3/dependency-check-$releaseNumber-release.zip
. In my case the release is 11.1.1. Then you can run unzip dependency-check-$releaseNumber-release.zip
, and we’re off. The most basic usage is dependency-check.sh --project "MyProject" --scan /path/to/your/project
. In my case, I don’t have a project to scan against, so I’m going to download a couple. Conveniently, OWASP also makes some vulnerable applications available for testing.
One such application is called WebGoat. Again, from their website, “WebGoat is a deliberately insecure application that allows interested developers just like you to test vulnerabilities commonly found in Java-based applications that use common and popular open source components.”
Another application is called JuiceShop. “OWASP Juice Shop is probably the most modern and sophisticated insecure web application! It can be used in security trainings, awareness demos, CTFs and as a guinea pig for security tools! Juice Shop encompasses vulnerabilities from the entire OWASP Top Ten along with many other security flaws found in real-world applications!”
They can be downloaded with git clone https://github.com/WebGoat/WebGoat.git
and git clone https://github.com/bkimminich/juice-shop.git
respectively.
I started with running a basic scan against WebGoat by running: dependency-check.sh --project "WebGoat" --scan WebGoat --nvdApiKey $APIKey
. This takes a while to run because it has to check against so many different entries in the NVD. After it does, the default output for a basic scan is an .html
report file which we can open and view in browser. It has a summary of the project, and the more details on each of the individual vulnerabilities discovered.
Here we can that the were 9 vulnerable dependencies with 45 vulnerabilities found. We also see that while the highest severity for 8 of the vulnerabilities is MEDIUM
, we also have 1 HIGH
vulnerability for a dependency called underscore-min.js
. So it makes sense to pick that one to analyze a little more thoroughly.
Here we see that the Identifier is pkg:javascript/underscore.js@1.10.2
and the File Path is WebGoat/src/main/resources/webgoat/static/js/libs/underscore-min.js
. We have the link to the CVE here and an explanation that the underscore.js
versions prior to 1.12.1
are vulnerable to Arbitrary Code Injection via the template function, particularly when a variable property is passed as an argument as it is not sanitized.
I know from the TryHackMe courses linked above that code injection via the template function occurs when a web application allows users to input or modify templates in a way that can be exploited by malicious users. If we read the linked Snyk advisories, we see that the is the case “particularly when the variable option is taken from .templateSettings as it is not sanitized.”
They also helpfully provide this Proof of Concept code:
const _ = require('underscore');
_.templateSettings.variable = "a = this.process.mainModule.require('child_process').execSync('touch HELLO')";
const t = _.template("")();
The suggested remediation steps are to upgrade underscore.js
to version 1.13.0-2, 1.12.1 or higher.
I figured it makes sense to try at least one more application to see if there’s anything interesting I might miss in just WebGoat. In this case, I note that Juice Shop has a couple of .zip
files that cause some errors such as [ERROR] Exception extracting archive 'passwordProtected.zip'
. If I remember correctly, this application has some files that are meant to be found by attackers as part of the training, so I decide to exclude .zip
files with --exclude **/**.zip
. I get a few more errors which require me to install npm
and yarn
, both with apt
. Eventually I run ./dependency-check/bin/dependency-check.sh --project "JuiceShop" --scan juice-shop --nvdApiKey $APIKey --out juiceshop --exclude '**/**.zip'
and check the results. We see a lot more here, too many to fit in one screenshot:
There are 56 vulnerable dependencies with 155 total vulnerabilities found. While the WebGoat application contained only 1 HIGH
vulnerability, the Juice Shop application contains 14 dependencies with a Highest Severity of CRITICAL
. To be fair, it is an intentionally vulnerable application.
The dependency with the highest number of vulnerabilities, including at least one Critical is lodash:2.4.2
with the identifier pkg:npm/lodash@2.4.2
. We can scroll down to check it out:
One thing I notice here is that the first vulnerability (GHSA-jf85-cpcp-j695 (NPM)
) explicitly seems to be from NPM, and it furthermore shows an NPM Advisory reference linking to https://nvd.nist.gov/vuln/detail/CVE-2019-10744. This seems important because the very next vulnerability listed is CVE-2019-10744
. So it looks like both of our CRITICAL
vulnerabilities for this dependency are actually the same thing. We check a Snyk advisory shown in both entries to find out more.
From that advisory, “Affected versions of this package are vulnerable to Prototype Pollution. The function defaultsDeep
could be tricked into adding or modifying properties of Object.prototype
using a constructor payload.”
I know from TryHackMe’s Web Application Pentesting path that prototypes are the core mechanism of inheritance in JavaScript. Every object in JavaScript has an internal link to a prototype object, which is used to share properties and methods. When you try to access a property or method on an object, JavaScript looks for it on the object first. If it doesn’t exist, it searches the prototype chain until it finds it or reaches the end (null
). So prototype pollution is a vulnerability that arises when an attacker manipulates an object’s prototype, impacting all instances of that object.
The advisory gives this PoC:
const mergeFn = require('lodash').defaultsDeep;
const payload = '{"constructor": {"prototype": {"a0": true}}}'
function check() {
mergeFn({}, JSON.parse(payload));
if (({})[`a0`] === true) {
console.log(`Vulnerable to Prototype Pollution via ${payload}`);
}
}
check();
This example shows the payload
JSON string being targeting the constructor.prototype
property with the goal of ultimately modifying the global Object.prototype
. Ultimately the guidance is to upgrade lodash
to version 4.17.12 or higher.
So that’s a very brief overview of the OWASP Dependency Check SCA tool. There are commercial tools with additional features, but for a FOSS tool like this, it’s certainly easy to see how it would be useful. It looks through the source code for any known vulnerabilities with any of the libraries in use and creates a small report on them with links to advisories and their entry in the NVD. Ultimately the analysis generated from a tool like this is only a start, and it’s important to evaluate the vulnerabilities in more detail, but it’s a nice boost to kick things off, especially when paired with Static Application Security Testing (SAST) and Dynamic Application Security Testing (DAST) tools which I’ll be checking out soon.