testssl Integration with DefectDojo
testssl Integration with DefectDojo
testssl.sh is an open source command line tool, maintained under the testssl organization on GitHub, that checks a server's TLS and SSL configuration on any port. It tests which protocol versions and cipher suites a service offers, inspects the certificate chain, and probes for known cryptographic flaws such as Heartbleed, ROBOT, and DROWN. It works against HTTPS and STARTTLS services alike, and writes results as plain text, HTML, JSON, or CSV. DefectDojo imports the CSV output.
testssl Integration with DefectDojo
We run testssl.sh against every externally reachable TLS endpoint we own, and DefectDojo is where those results turn into tracked work. A testssl.sh run produces a long list of checks for one host at one moment. Imported into DefectDojo, every check that came back with a problem becomes a Finding on the right Asset, tied to the host and port it was found on, with a severity, an owner, and an SLA. When an infrastructure team finally disables TLS 1.0 on a load balancer, the next import shows it, instead of someone comparing two CSV files by eye.
Why testssl Matters
TLS misconfiguration is rarely dramatic, but it is persistent. Old protocol versions, weak ciphers, and expiring certificates tend to survive on forgotten hosts long after the main site was fixed.
- testssl.sh runs from a shell with no agent and few dependencies, so it fits in cron jobs, CI stages, and ad hoc audits.
- It checks more than the web server on 443. Mail, LDAP, database, and other STARTTLS services can be tested with the same tool.
- Each check carries a testssl.sh severity and, where one applies, a CVE and CWE, which gives the results a structure that maps onto a finding tracker.
- On its own, the output has no history. Without a platform behind it, nobody can tell whether a weak cipher is new on this host or has been there for a year.
Advantages of This Integration
What we gained by sending testssl.sh results through DefectDojo:
- Noise filtered at import. The parser skips every check that testssl.sh rated OK, along with the overall rating and score rows, so only checks that need attention become Findings.
- Host and port context. Each Finding carries an endpoint built from the scanned host name and port, so the same weakness on two services stays clearly attributed.
- CVE-aware findings. Checks that reference CVEs keep them as vulnerability IDs, so DefectDojo can filter and report on, for example, every host still exposed to a specific TLS flaw.
- A remediation lifecycle. Reimporting a fresh CSV into the same Test closes checks that now pass, adds new problems, and reactivates anything that regressed.
- One view of infrastructure risk. TLS findings sit on the same Asset as network scanner, container, and application results, under the same SLA rules.
How This Integration Works
DefectDojo imports testssl.sh results with the Testssl Scan scan type. The parser expects the CSV layout with the columns id, fqdn/ip, port, severity, finding, cve, and cwe.
1. Produce a CSV report. Run testssl.sh against the target and write the CSV to a file:
testssl.sh --csvfile testssl-report.csv https://shop.example.com
If one CSV contains rows for several hosts, the parser groups rows per check, so an identical result on several hosts becomes one Finding with multiple endpoints.
2. Import it. In the UI, open the Engagement, choose Import Scan Results, select Testssl Scan, and upload the CSV. For automation, use the import API, available in both Community Edition and DefectDojo Pro:
curl "https://YOUR_INSTANCE/api/v2/import-scan/" \
-H "Authorization: Token $DD_API_TOKEN" \
-F "scan_type=Testssl Scan" \
-F "file=@testssl-report.csv" \
-F "product_name=public-edge" \
-F "engagement_name=TLS Monitoring" \
-F "auto_create_context=true"
DefectDojo Pro users can run the same import from a pipeline with Universal Importer:
universal-importer import \
--defectdojo-url "https://YOUR_INSTANCE.cloud.defectdojo.com/" \
--scan-type "Testssl Scan" \
--report-path "./testssl-report.csv" \
--product-name "public-edge" \
--engagement-name "TLS Monitoring" \
--auto-create-context
3. Reimport on a schedule. For hosts you check repeatedly, send later reports to /api/v2/reimport-scan/ against the same Test so passing checks are mitigated and history stays in one place.
Data Granularity: What Gets Imported
| DefectDojo Field | Source in testssl CSV | Notes |
|---|---|---|
| Title | id |
The testssl.sh check ID, for example DROWN or cipherlist_LOW |
| Description | finding |
testssl.sh's result text for that check |
| Severity | severity |
LOW, MEDIUM, HIGH, CRITICAL map directly; INFO, WARN, and FATAL become Info |
| Skipped rows | severity and id |
OK results, rating and score rows, and grade cap reasons are not imported |
| Vulnerability IDs | cve |
One Finding per listed CVE when a check names several |
| CWE | cwe |
Parsed from values such as CWE-310 |
| References | finding |
Cipher checks get a ciphersuite.info link for the named suite |
| Endpoint | fqdn/ip, port |
Host name portion before the slash, plus the port |
| Occurrences | Repeated rows | Same check, text, and CVE across hosts merge, adding endpoints |
| Deduplication | Legacy algorithm | No per-scanner hash setting; the default algorithm considers endpoints |
Use Cases
For external attack surface checks: A weekly job runs testssl.sh across every public host name and reimports each result into a Test per host. The security team sees exactly which hosts still offer deprecated protocols, and each fix is recorded when the next run passes.
Before a compliance assessment: PCI DSS and similar reviews look closely at TLS versions and cipher choices. With testssl.sh findings in DefectDojo, an assessor can see when a weak configuration was found, who owned it, and when it was closed.
After a load balancer or CDN change: A platform team rolls out a new TLS policy. Running testssl.sh and reimporting shows, per service, which checks the change fixed and which services were missed because they terminate TLS somewhere else.
For internal services: Databases, mail relays, and directory services often get less TLS attention than the website. Testing them with STARTTLS and importing into the owning Asset puts them under the same SLAs as the public edge.
Operational Tips
- Expect a lot of Info findings. testssl.sh reports many INFO and WARN rows that the parser keeps as Info, so set
minimum_severity=Lowon import if you only want actionable weaknesses. - FATAL rows, such as a target that could not be reached, are imported as Info. Review them after scheduled runs, since a connection failure can hide a host from the results.
- A check that lists several CVEs becomes several Findings, one per CVE. Count findings with that in mind when you compare DefectDojo totals with the raw CSV.
- Use one Test per host or per scan target list and reimport into it, so you get a clean open to mitigated history rather than a new Test every week.
- Tag imports with the environment or network zone (for example
tags=external,tls) so TLS findings can be filtered apart from other infrastructure results. - Because deduplication for this scan type falls back to the legacy algorithm, which compares endpoints, keep host names consistent between runs. Scanning by IP one week and by name the next will produce separate findings.