Vuls Integration with DefectDojo
Vuls Integration with DefectDojo
Vuls is an open source, agentless vulnerability scanner for Linux and FreeBSD, written in Go and published by Future Architect on GitHub. It inventories the packages installed on a host, either over SSH or locally, and matches them against vulnerability databases such as NVD, JVN, and each distribution's own security tracker. Results are written per server, and vuls report -format-json produces the JSON report DefectDojo imports.
Vuls Integration with DefectDojo
We picked Vuls because it scans our Linux fleet without installing an agent and its fast scan mode puts almost no load on production hosts. What it does not give us is a place to assign, track, and age those CVEs. Importing Vuls JSON into DefectDojo gives each CVE and package pair its own finding with the host, the fixed version, and whether the CVE is known to be exploited, then reimports show what patching actually closed.
Why Vuls Matters
Operating system packages are a large share of the CVEs on any server, and they are easy to lose track of between patch windows.
- It is agentless, so it covers hosts where installing software is not an option.
- It pulls CVE detail from several sources and reports the scores from each.
- It records how each vulnerability was detected and whether a fix is available yet.
- It notes when a CVE appears in a known-exploited catalogue or has public exploits, which matters more for prioritization than a score alone.
- Its raw output is a per-scan snapshot, with no notion of ownership or remediation history.
Advantages of This Integration
Running Vuls results through DefectDojo changes how the team works with them:
- One finding per thing to upgrade. A CVE affecting both
curlandlibcurl4becomes two findings, because each package is a separate upgrade. A CVE with no package attributed still produces one finding instead of being dropped. - Conservative severity. Vuls sources often disagree. DefectDojo takes the highest CVSS score across all of them, preferring newer CVSS versions at a tie, and maps it to standard bands.
- Unscored stays Info. A CVE that no source has scored yet imports as Info rather than being inflated to Medium, so real scored findings are not buried.
- Exploit context in the finding. KEV listing and the count of known public exploits are written into the description, so triage can start with what attackers already use.
- Lifecycle through reimport. Reimporting the next scan closes CVEs that patching removed and reopens any that return.
- Platform features. SLAs, assignment, Jira, risk acceptance for packages with no fix yet, and metrics all apply.
How This Integration Works
DefectDojo imports Vuls output with the Vuls Scan scan type, using UI Import, API Import, or Universal Importer in DefectDojo Pro.
1. Scan and write a JSON report. With Vuls configured for your servers:
vuls scan
vuls report -format-json
Vuls writes one ScanResult per scanned host. DefectDojo accepts a single host's result or a JSON array of several hosts. The scan mode you choose in Vuls (fast scan without root, fast root scan, remote over SSH, local, or server mode) changes what Vuls can see on the host, but the JSON report format DefectDojo reads is the same, so you can mix modes across your fleet without changing the import step. If a single file holds several hosts, all of them land in the Test you import into, so decide up front whether you want one Test per host or one per server group.
2. Import it. In the UI, open the Engagement, choose Import Scan Results, select Vuls Scan, and upload the file. Through the API, in Community Edition or DefectDojo Pro:
curl "https://YOUR_INSTANCE/api/v2/import-scan/"
-H "Authorization: Token $DD_API_TOKEN"
-F "scan_type=Vuls Scan"
-F "file=@web01.json"
-F "product_name=web01"
-F "engagement_name=OS Packages"
-F "auto_create_context=true"
With Universal Importer in DefectDojo Pro:
universal-importer import
--defectdojo-url "https://YOUR_INSTANCE.cloud.defectdojo.com/"
--scan-type "Vuls Scan"
--report-path "./web01.json"
--product-name "web01"
--engagement-name "OS Packages"
--auto-create-context
3. Reimport after each scan. Send later reports for the same host to /api/v2/reimport-scan/ against the same Test so fixed CVEs are mitigated and history stays in one place.
Data Granularity: What Gets Imported
| DefectDojo Field | Source in Vuls Report | Notes |
|---|---|---|
| Title | CVE ID and source title | CVE-ID: title when a source supplies a title, otherwise the CVE ID |
| Severity | Highest CVSS score across cveContents |
9.0+ Critical, 7.0+ High, 4.0+ Medium, above 0 Low, unscored Info |
| Description | Summary and context | CVE, server, platform, package, fixed-in, fix state, highest score, detection method, KEV, exploit count, source link |
| Mitigation | mitigations URLs |
Listed one per line |
| Component Name / Version | Affected package | Installed package name and version |
| CVSS v3 Vector / Score | cvss3Vector, best score |
Score set only when the highest score is CVSS 3.x |
| CWE | cweIDs |
First CWE found across sources |
| Vulnerability IDs | CVE ID | Enables CVE search and filtering |
| Vuln ID from Tool | CVE ID | |
| Finding type | Static | Package inventory, nothing probed |
| Deduplication | Hashcode | vulnerability_ids, component_name |
Use Cases
Patch window verification: Operations patches a group of servers on Sunday. Monday's Vuls scans are reimported, and the Test shows which CVEs closed and which packages were missed.
Prioritizing by exploitation: A security lead filters Critical and High findings and reads the description for KEV listing and public exploit counts, so the first tickets go to CVEs attackers are actively using.
Hosts without agents: Appliances and locked-down servers where agents are not allowed still get covered, because Vuls scans over SSH and DefectDojo only needs the report.
Tracking unfixed CVEs: Findings whose fix state shows no patch yet are risk-accepted with an expiration date, then reviewed when the distribution ships a fix.
Operational Tips
- Keep one host per Asset, or at least per Test. The dedupe hash is CVE plus package name, with no host in it, so the same CVE in the same package on two servers in one Asset can be treated as duplicates.
- Reimport each host into its own Test so mitigation reflects that host, not a merged view.
- Expect Info findings for freshly published CVEs that no source has scored yet. Review them periodically rather than filtering them out entirely.
- Use
minimum_severityif Low OS package findings overwhelm the team, and lower it once the backlog is under control. - Tag imports with environment or role (for example
tags=prod,web) so you can report exposure by tier. - Because severity comes from the highest score across sources, it may be higher than your distribution's own rating. Agree on that convention with operations before setting SLAs.