All integrations

ZAP Integration with DefectDojo

ZAP Integration with DefectDojo

ZAP (Zed Attack Proxy) is an open source dynamic application security testing (DAST) tool for web applications and APIs. It began as an OWASP project and, since 2024, its core team has continued development under the ZAP by Checkmarx name while the tool remains open source. ZAP crawls a running application, passively inspects the traffic it sees, and can actively probe for issues such as injection flaws, missing security headers, and insecure cookies. It runs as a desktop proxy, a headless daemon, or a Docker container, and its reports include XML, JSON, HTML, and SARIF formats.

ZAP Integration with DefectDojo

ZAP is the DAST scanner we can run everywhere: on every staging deploy, in nightly full scans, and on demand during a pentest. DefectDojo is what turns those runs into a remediation list. Each ZAP alert becomes a Finding on the Asset for that application, with every affected URL attached as an endpoint and the request and response evidence kept with it. When a fix ships and the next scan stops reporting the alert, a reimport closes it. That history is what we need to report on DAST risk instead of rereading HTML reports.

Why ZAP Matters

Static tools can't see how an application behaves once it is deployed with its real configuration, proxies, and authentication. ZAP tests that running system.

  • It finds issues that only appear at runtime, such as missing headers, cookie flags, information leaks in responses, and server misconfiguration.
  • The packaged baseline scan is passive and fast enough to run on every deployment without harming the target.
  • It is open source and scriptable, with an Automation Framework that fits CI pipelines.
  • It records evidence for each instance, which helps developers reproduce the problem.
  • On its own, each scan is a separate report. Without a platform, nobody knows which alerts are new, which were accepted, and which were fixed last sprint.

Advantages of This Integration

What we gained by sending ZAP results through DefectDojo:

  • One Finding per alert, many endpoints. The parser groups every instance of an alert under one Finding with each URL as an endpoint, which matches how teams fix these issues.
  • Deduplication on title, CWE, and severity. Rescanning the same application doesn't recreate findings, and the same alert type is tracked as one item per Asset.
  • Evidence kept with the finding. Requests and responses (or ZAP's method, parameter, and evidence fields) are stored on the Finding for developers to review.
  • A remediation lifecycle. Reimporting into the same Test mitigates alerts that no longer appear and reactivates ones that return after a regression.
  • SLAs and ownership. ZAP risk levels map onto DefectDojo severities, so DAST findings get owners, deadlines, Jira tickets, and risk acceptances like any other finding.

How This Integration Works

DefectDojo imports ZAP results with the ZAP Scan scan type. It reads the traditional XML report, with or without requests and responses, and the file name must end in .xml.

1. Generate an XML report. With the ZAP baseline scan in Docker:

docker run -v $(pwd):/zap/wrk/:rw -t ghcr.io/zaproxy/zaproxy:stable \
  zap-baseline.py -t https://staging.example.com -x zap-report.xml

The full scan script (zap-full-scan.py) and API scan script (zap-api-scan.py) accept the same -x option. If you drive ZAP with the Automation Framework, add a report job using the traditional-xml template, or traditional-xml-plus to include full request and response headers and bodies.

2. Import it. In the UI, open the Engagement, choose Import Scan Results, select ZAP Scan, and upload the file. From a pipeline with the API (Community Edition and DefectDojo Pro):

curl "https://YOUR_INSTANCE/api/v2/import-scan/" \
  -H "Authorization: Token $DD_API_TOKEN" \
  -F "scan_type=ZAP Scan" \
  -F "file=@zap-report.xml" \
  -F "product_name=customer-portal" \
  -F "engagement_name=Staging DAST" \
  -F "auto_create_context=true"

DefectDojo Pro users can run the same import with Universal Importer:

universal-importer import \
  --defectdojo-url "https://YOUR_INSTANCE.cloud.defectdojo.com/" \
  --scan-type "ZAP Scan" \
  --report-path "./zap-report.xml" \
  --product-name "customer-portal" \
  --engagement-name "Staging DAST" \
  --auto-create-context

3. Reimport after each scan. For a target you scan on a schedule, send later reports to /api/v2/reimport-scan/ against the same Test so DefectDojo can close what was fixed.

Data Granularity: What Gets Imported

DefectDojo Field Source in ZAP Report Notes
Title alert The ZAP alert name
Severity riskcode 0 Info, 1 Low, 2 Medium, 3 High. ZAP has no Critical level
Scanner Confidence riskcode Derived from the risk code, not ZAP's confidence element
Description desc HTML converted to Markdown
Mitigation solution HTML converted to Markdown
References reference HTML converted to Markdown
CWE cweid Set when numeric
Vulnerability ID from tool pluginid The ZAP scan rule ID
Endpoints instances/instance/uri One per instance; query string and fragment removed
Request / Response requestheader, requestbody, responseheader, responsebody Without these, the request holds method, parameter, and attack fields, and the response holds the evidence
Finding type Dynamic All ZAP findings are dynamic
Deduplication Hashcode Title, CWE, severity

Each site element in the report is processed, so a scan that covered several hosts produces endpoints on each of them under the matching alert.

Use Cases

On every staging deployment: The pipeline runs the ZAP baseline scan after deploy and reimports the result into a Test for that environment. New passive alerts show up within minutes, and alerts fixed by a configuration change close automatically.

For scheduled full scans: A nightly active scan of a pre-production environment imports into a separate Test, so the deeper results keep their own history and don't overwrite the baseline Test's lifecycle.

Across an application portfolio: A platform team scans 50 internal web applications with the same ZAP configuration and imports each into its own Asset. Security leads then compare header and cookie hygiene across teams from DefectDojo metrics.

During manual testing: A tester exports the XML report from a ZAP desktop session and imports it into the pentest Engagement, so their alerts sit next to scanner and manual findings for the same application.

Operational Tips

  • Don't rely on Scanner Confidence for ZAP findings. The parser fills it from the risk code, so it mirrors severity rather than ZAP's confidence rating.
  • ZAP's highest risk is High. If your SLA policy keys on Critical, decide how ZAP High findings should be handled, or raise individual findings during triage.
  • Use separate Tests for baseline and full scans. Reimporting a passive scan into a Test populated by an active scan would mitigate every active-only alert.
  • Use the traditional-xml-plus template when developers need full requests and responses, and plain traditional-xml when report size matters.
  • Because deduplication ignores the URL, one alert type is one Finding per Asset. If you need to track separate applications separately, give each its own Asset.
  • Mark informational alerts you never act on as false positives or accepted risk once, rather than lowering minimum_severity and losing visibility of new Info alerts.