So you think your application is safe…

No matter how much effort you’ve put into writing secure code, critical security flaws can still find their way into your project through its dependencies. Today, an average of 80% of a new application’s code is comprised of third-party libraries and frameworks, a quarter of which contain known vulnerabilities¹.

Due to the widespread prevalence of these security flaws, and the degree of difficulty in detecting them, the OWASP Foundation has identified Using Components with Known Vulnerabilities in their most recent list of the top 10 security threats to web applications.

Components, such as libraries, frameworks, and other software modules, almost always run with full privileges. If a vulnerable component is exploited, such an attack can facilitate serious data loss or server takeover. Applications using components with known vulnerabilities may undermine application defenses and enable a range of possible attacks and impacts.

— OWASP #9

Dependency Check

In response to this problem, OWASP created Dependency Check, a Java app that scans for vulnerable dependencies.

Dependency Check utilizes a variety of methods to accurately recognize versions of third party components based on their Common Platform Enumeration (CPE) identifiers. Then it references the CPEs against the National Vulnerability Database in order to identify Common Vulnerabilities and Exposures (CVEs).

Dependency Check already features plugins for MavenAnt, and Jenkins. Now, with Package Monitor (PacMon for short), Dependency Check can be fully integrated into a TeamCity build step!

PacMon (Package Monitor)

At its core, PacMon is a PowerShell script that runs the command-line version of Dependency Check and parses the results into a format that can be consumed by TeamCity. Specifically, the script reports on each individual dependency as though it were an automated test that fails if one or more known vulnerabilities are found. False positives may be ignored using a suppression XML file (more on that, later).

Download PacMon from Excella Labs and add it to your project to get started!


For testing purposes, PacMon is bundled with Lambchop, a VS2013 test solution containing over 20 NuGet package references, several of which have known vulnerabilities of varying severity.

It is worth noting that PacMon will not be able to scan Lambchop (or any other Visual Studio solution) until the project has been built at least once, as its NuGet packages are only downloaded during the build process.

Configuring TeamCity

Navigate to the Configuration Settings of a new or existing Build in your project. Select Build Steps from the sidebar menu on the left.

Click the Add build step button.

Select the PowerShell runner type from the first dropdown.

Specify that PowerShell is run in Version 4.0 mode**.**

Enter the path of the script file, pacmon.ps1, relative to the checkout directory. For example, if you put PacMon in your project’s util folder, the path might look something like MyApputilPacMonpacmon.ps1.

Click the Expand link in the Script arguments section and add the required -target parameter, which specifies the relative path to your application.

In the example given above:

-java %env.JAVA_EXE% ensures that PacMon is able to locate the Java executable by passing TeamCity’s pre-defined environment variable to the script.

-target .Lambchop points PacMon at the Lambchop folder in the checkout directory. This is the path that will be scanned for dependencies with known vulnerabilities.

-etc “-n” tells PacMon not to update the vulnerability database before scanning. The database must be updated at least once, though, so this parameter should never be included the first time that PacMon runs.

Click the Save button to finalize the new Build Step.

Reading the Results

PacMon translates Dependency Check’s findings into a suite of tests, and each identified CPE equates to an individual test. One or more known vulnerabilities will cause the test to fail, unless the CPE or CVE has been suppressed (see “Suppressing False Positives” below), in which case it will show up as ignored.

For a more detailed report, click on the build result summary:

Expanding a failing dependency will show a list of associated CVEs, each with a degree of severity (Low, Medium, High), followed by a brief summary of the vulnerability.

To delve into even greater detail, expand the build step’s **Artifacts **and click on the dependency report, named vulnerabilities.html by default.

This report, generated by Dependency Check, contains links to relevant entries in the National Vulnerability Database. It also allows you to easily suppress specific vulnerabilities (CVEs) or entire dependencies (CPEs).

Suppressing False Positives

To ignore one or more failing tests, navigate to the most recent dependency report artifact (see “Reading the Results” above). Clicking the suppress button next to a CVE will allow you to ignore a specific vulnerability, whereas the suppress button next to a CPE will ignore all vulnerabilities pertaining to the respective dependency.

When you click suppress, a pop-up modal will appear containing a snippet of XML.

Press Ctrl+C to copy the highlighted XML to your clipboard and close the modal. Open the suppression file (suppress.xml is included with PacMon) and paste the copied XML within the  tags.

?xml version="1.0" encoding="UTF-8"?> 041DCCAF76E8441E735CC078F93F1F3B0003D94E CVE-2008-0333

Save and commit the suppression file. The next time PacMon runs on TeamCity, it should report any suppressed CPEs/CVEs as ignored tests.


**PacMon Build Step Fails (Exit code 1) **

Examine the build log for the failing step on TeamCity. If PacMon complains that “‘java’ is not recognized as an internal or external command,” you can use TeamCity’s pre-defined environment variable by specifying the following script argument:

-java %env.JAVA_EXE%

PacMon Fails to Identify a Known Vulnerability (False Negative)

While false positives are easily ignored (see “Suppressing False Positives” above), resolving a false negative requires adding a new CVE to the National Vulnerability Database. This is a lengthy process that begins with submitting the vulnerability to CERT.

PacMon Can’t Find Any CPEs in a Solution

If the Build Step containing PacMon completes without reporting on any tests, that may indicate a misconfiguration of the **-target **script argument (see “Configuring TeamCity” above).

If PacMon is scanning the correct path, it is possible that the solution has not yet been built. NuGet packages are only downloaded when a solution builds, and typically not checked in via VCS, so an un-built project most likely won’t have anything to scan.


Using third-party libraries and frameworks poses a real risk to the security of your application, so it is important to identify potential threats in a timely fashion. By integrating OWASP Dependency Check into your build pipeline with PacMon, you can rest assured that known vulnerabilities aren’t finding their way into your application.