Appearance
OWASP Dependency Check
OWASP Dependency Check (ODC) scans project dependencies against the National Vulnerability Database (NVD) and detects known vulnerable libraries. It runs as Stage 6 in the DevSecOps pipeline, after Trivy dependency scanning, providing a second-opinion scan with a different vulnerability database.
Positioning in the DevSecOps Pipeline
Pipeline Stages
──────────────────────────────────────────────────────────────
Stage 1: Gitleaks — Secret scanning
Stage 2: Build — dotnet restore / npm install
Stage 3: SonarCloud — SAST (code quality + security)
Stage 4: Trivy (fs) — Dependency CVE scan
Stage 5: Trivy (config) — IaC misconfiguration scan
Stage 6: OWASP DC — NVD-based dependency CVE scan ◄──
Stage 7: (reserved)
Stage 8: Docker Build — Multi-stage Dockerfile
Stage 9: Trivy (image) — Container image CVE scan
Stage 10: Syft SBOM — Software Bill of Materials
...
──────────────────────────────────────────────────────────────Why Both Trivy and OWASP DC?
Trivy and OWASP DC use different vulnerability databases and detection methods. Trivy is faster and catches more container-layer issues. OWASP DC is deeper on Java/NuGet ecosystems and uses NVD as its authoritative source. Running both maximizes coverage with minimal false-negative risk.
Ecosystems Scanned
| Ecosystem | Files Analyzed |
|---|---|
| .NET / NuGet | *.csproj, packages.lock.json |
| Node.js / npm | package-lock.json, yarn.lock |
| Java / Maven | pom.xml, *.jar |
| Java / Gradle | build.gradle, *.jar |
OWASP DC downloads and parses dependency metadata then cross-references against NVD CVE records using CPE (Common Platform Enumeration) matching.
Pipeline Integration
Stage 6 pipeline task:
yaml
- stage: OwaspDependencyCheck
displayName: 'Stage 6 - OWASP Dependency Check'
dependsOn: TrivyIaC
jobs:
- job: OwaspDC
pool:
vmImage: 'ubuntu-latest'
steps:
- checkout: self
- task: Bash@3
displayName: 'Run OWASP Dependency Check'
inputs:
script: |
mkdir -p $(Build.ArtifactStagingDirectory)/owasp-dc
docker run --rm \
-v $(Build.SourcesDirectory):/src \
-v $(Build.ArtifactStagingDirectory)/owasp-dc:/report \
-v $(Pipeline.Workspace)/.odc-data:/usr/share/dependency-check/data \
owasp/dependency-check:latest \
--project "Microtec ERP" \
--scan /src \
--format HTML \
--format JSON \
--format SARIF \
--out /report \
--failOnCVSS $(owaspDcFailThreshold) \
--suppression /src/DevSecOps/config/owasp-suppressions.xml \
--enableExperimental \
--disableYarnAudit \
--log /report/owasp-dc.log
- task: PublishBuildArtifacts@1
condition: always()
displayName: 'Publish OWASP DC Report'
inputs:
pathToPublish: '$(Build.ArtifactStagingDirectory)/owasp-dc'
artifactName: 'security-owasp-dc'Failure Threshold Configuration
The pipeline uses the --failOnCVSS flag to block on high-severity findings:
| Variable | Value | Meaning |
|---|---|---|
owaspDcFailThreshold | 7 | Block on CVSS score ≥ 7.0 (HIGH and CRITICAL) |
The threshold is defined in the mic-erp-{env}-vars variable group in Azure DevOps. It can be raised to 9 (CRITICAL only) during a grace period when remediating findings.
yaml
# Variable group setting
owaspDcFailThreshold: 7 # dev, stage, preprod, uat
owaspDcFailThreshold: 9 # production (CRITICAL only — blocks release)Suppression File
Known false positives and accepted risks are recorded in the suppression file. This file is version-controlled and requires peer review before changes are merged.
Location: DevSecOps/config/owasp-suppressions.xml
xml
<?xml version="1.0" encoding="UTF-8"?>
<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.3.xsd">
<!--
CVE-2024-XXXXX: False positive — affects Node.js CLI tooling only.
The affected package (X) is a dev dependency not included in the production bundle.
Accepted by: M.Araby | Date: 2025-04-01 | Expires: 2025-10-01
Ticket: ERP-5678
-->
<suppress until="2025-10-01Z">
<notes>Dev-only dependency — not in production bundle. See ERP-5678.</notes>
<cve>CVE-2024-XXXXX</cve>
<packageUrl regex="true">^pkg:npm/affected-package@.*$</packageUrl>
</suppress>
<!--
CVE-2024-YYYYY: Accepted risk — .NET runtime patched in dotnet 8.0.5+.
Base image updated to 8.0.5 as of 2025-03-15. ODC has stale data.
Accepted by: M.Araby | Date: 2025-03-15 | Expires: 2025-09-15
-->
<suppress until="2025-09-15Z">
<notes>Resolved in .NET 8.0.5 base image update. Awaiting ODC DB refresh.</notes>
<cve>CVE-2024-YYYYY</cve>
<filePath regex="true">.*aspnetcore-runtime.*</filePath>
</suppress>
</suppressions>Suppression Entry Requirements
Every suppression entry must include:
| Field | Requirement |
|---|---|
until date | Expiry date — entry must be re-reviewed before this date |
notes | Justification: why is it suppressed? |
| CVE ID | Specific CVE, not wildcard |
| Package URL or file path | Scope the suppression to the specific dependency |
| Accepted by | Name in a comment |
| Ticket reference | ADO work item number |
Expired Suppressions Block the Pipeline
OWASP Dependency Check automatically ignores suppression entries that have passed their until date. The finding will re-appear in the next scan. Monitor suppression expiry dates via Check-ExpiredSecrets.ps1 or a calendar reminder.
NVD Data Cache
OWASP DC downloads the NVD database on first run (~500 MB). Subsequent runs use the cached data mounted at /usr/share/dependency-check/data:
yaml
# Mount the NVD cache between pipeline runs (Pipeline.Workspace persists on self-hosted agents)
-v $(Pipeline.Workspace)/.odc-data:/usr/share/dependency-check/dataOn Microsoft-hosted agents (ephemeral), the cache is not preserved between runs. This adds ~3–5 minutes for the NVD data download. To mitigate:
- Use a self-hosted build agent with persistent workspace
- Or use the
--noupdateflag with a pre-warmed cache artifact
yaml
# Alternative: download NVD data as a pipeline artifact
- task: DownloadPipelineArtifact@2
inputs:
source: 'specific'
project: '$(System.TeamProject)'
pipeline: 'owasp-dc-data-refresh' # Weekly data refresh pipeline
artifactName: 'nvd-data-cache'
targetPath: '$(Pipeline.Workspace)/.odc-data'Reading the Report
The HTML report (published as a pipeline artifact) includes:
| Section | Content |
|---|---|
| Summary | Total dependencies scanned, CVE count by severity |
| Dependencies | Each dependency with its identified CPE and matched CVEs |
| Vulnerabilities | CVE detail: CVSS score, description, affected versions, fix version |
| Suppressed | Findings that were suppressed with justification |
To view the report:
- Go to the pipeline run in Azure DevOps
- Click Artifacts →
security-owasp-dc - Download
dependency-check-report.html - Open in browser
Remediating Findings
When OWASP DC blocks the pipeline:
- Identify the vulnerable package from the HTML report (dependency name + CVE)
- Check for a fixed version in the CVE advisory or package release notes
- Update the package in
.csprojorpackage.json - If no fix is available:
- Assess actual exploitability in the Microtec context
- If non-exploitable (e.g., test-only dependency, affected code path not reachable): add a time-limited suppression with a ticket reference
- If exploitable: escalate to security team; consider removing the dependency
Running Locally
bash
# Install via Docker (recommended)
docker run --rm \
-v $(pwd):/src \
-v ~/.odc-data:/usr/share/dependency-check/data \
owasp/dependency-check:latest \
--project "Microtec Local Scan" \
--scan /src/Platforms \
--format HTML \
--out ./owasp-report \
--suppression DevSecOps/config/owasp-suppressions.xml \
--failOnCVSS 7
# View report
open owasp-report/dependency-check-report.htmlRelated Documentation
- Pipeline Stages — Full 16-stage DevSecOps pipeline overview
- Trivy — Complementary dependency and image scanner
- Gitleaks — Stage 1 secret scanning
- SonarCloud — Stage 3 SAST scanning