Modern Java applications are rarely written from scratch; we rely on a massive ecosystem of open-source libraries. While this accelerates development, it introduces a significant risk: transitive vulnerabilities. If one of your dependencies has a known security hole, your entire application is exposed. That’s where Software Composition Analysis (SCA) comes in.
In this guide, I’ll show you how to use OWASP Dependency Check in Maven to automatically scan your project for known vulnerabilities (CVEs). I’ve integrated this into several production pipelines, and it’s one of the most effective ways to prevent “Log4Shell” style disasters before they hit production.
Prerequisites
Before we dive into the configuration, ensure you have the following ready:
- Java JDK 8 or higher installed.
- Apache Maven 3.x installed and configured in your system PATH.
- A Maven-based project (even a simple “Hello World” will work for testing).
- Internet access (the plugin needs to download the NVD – National Vulnerability Database).
Step 1: Add the OWASP Dependency Check Plugin to pom.xml
To get started, you need to add the dependency-check-maven plugin to the <build> section of your pom.xml. I recommend placing it in the <plugins> block so it’s available for execution during your build lifecycle.
<build>
<plugins>
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>9.0.9</version>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
By adding the check goal to the executions block, the scan will run automatically during the verify phase of the Maven lifecycle.
Step 2: Running the Security Scan
You can trigger the scan in two ways. Either run the full Maven lifecycle or call the plugin directly. In my experience, calling the plugin directly is faster for local development.
Run the following command in your terminal:
mvn org.owasp:dependency-check-maven:check
Note: The first time you run this, it will take a long time (possibly 5-10 minutes). This is because the plugin is downloading and indexing the entire National Vulnerability Database (NVD) into a local H2 database. Subsequent runs will be significantly faster as they only fetch updates.
Step 3: Analyzing the Report
Once the build completes, the plugin generates a detailed HTML report. You can find it in the target directory:
target/dependency-check-report.html
Open this file in any browser. The report lists every dependency found in your project and flags those with associated CVEs. It categorizes them by severity: Low, Medium, High, and Critical. As shown in the report, you’ll see the CVE ID, the CVSS score, and a link to the official vulnerability description.
Step 4: Failing the Build on Vulnerabilities
Simply knowing there is a vulnerability isn’t enough; we want the build to fail if a high-severity vulnerability is detected. This prevents insecure code from even reaching the artifact repository.
Update your plugin configuration to include the failBuildOnCVSS parameter:
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>9.0.9</version>
<configuration>
<failBuildOnCVSS>7.0</failBuildOnCVSS>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
In the example above, I’ve set the threshold to 7.0. Any vulnerability with a CVSS score of 7.0 (High) or above will cause the Maven build to fail. This is a critical step when you learn how to automate security testing in CI/CD pipeline.
Pro Tips for Power Users
- Handling False Positives: Not every flagged CVE applies to how you use a library. You can create a
suppression.xmlfile to ignore specific CVEs. Add the path to this file in the<configuration>block using<suppressionFiles>. - Use an NVD Mirror: In large corporate environments, having 50 developers download the NVD database simultaneously can lead to IP blocking by NIST. I recommend setting up a centralized NVD mirror or using a database share.
- Complementary Tools: While OWASP Dependency Check is great for known CVEs, you might want to compare it with others. I’ve written a detailed breakdown of Snyk vs SonarQube for security testing if you’re looking for more advanced static analysis.
Troubleshooting Common Issues
1. NVD API Rate Limiting
You might see errors regarding 403 Forbidden or rate limits. Since 2024, the NVD requires an API key for reliable access. You can request one from the NIST website and add it to your configuration:
<nvdApiKey>your-api-key-here</nvdApiKey>
2. Build taking too long
If the scan is slowing down your local development, remove the <execution> block and run the scan manually once a day or only on the CI server.
What’s Next?
Now that you’ve mastered how to use OWASP Dependency Check in Maven, the next logical step is to ensure these checks are enforced automatically. Don’t rely on manual runs. Integrate this into your Jenkins, GitHub Actions, or GitLab CI pipeline to ensure that no vulnerable dependency ever reaches your production environment.