Home Technical Support Dynamic Application Security Testing with OWASP ZAP: Scans, Output, and Failures

Dynamic Application Security Testing with OWASP ZAP: Scans, Output, and Failures

Last updated on Sep 08, 2026

Dynamic Application Security Testing with OWASP ZAP: Scans, Output, and Failures

The Dynamic Analysis Using ZAP exercise teaches how to run OWASP ZAP baseline scans against web applications. This exercise appears across 5 courses. This article covers scan configuration, output formats, and common failures.


Table of Contents

  1. ZAP Baseline Scan Command
  2. Target URL Must Be Accessible
  3. Scan Takes 5+ Minutes
  4. JSON Output with Volume Mount
  5. Authenticated Scans
  6. Scan Result Categories
  7. Machine Timeout and 404 Errors
  8. Common Questions

ZAP Baseline Scan Command

Running a Baseline Scan

The exercise uses the hysnsec/zap:2.16.1 Docker image:

docker run --rm hysnsec/zap:2.16.1 zap-baseline.py -t https://prod-<machine-id>.lab.practical-devsecops.training

Key concept: The Docker image is auto-pulled if not present locally. No need for docker pull first.

Baseline Scan Options

Flag Purpose
-t target Target URL with protocol (required)
-m mins Minutes to spider (default: 1)
-l level Minimum level: PASS, IGNORE, INFO, WARN, FAIL
-J file.json JSON report output
-r file.html HTML report output
-w file.md Markdown report output
-x file.xml XML report output
-I Don't fail on warnings
-a Include alpha passive scan rules
-j Use Ajax spider

Target URL Must Be Accessible

Connection Refused or Timeout

If the target application isn't running or isn't reachable from the DevSecOps Box:

ERROR: Target URL is not accessible

Fix: Verify the target is up:

curl -s -o /dev/null -w "%{http_code}" https://prod-<machine-id>.lab.practical-devsecops.training

A 200 response means the target is accessible. 000 means connection refused.

Wrong URL Pattern

The target URL must use the correct pattern:

https://prod-<machine-id>.lab.practical-devsecops.training

Common mistake: Using http:// instead of https://, or omitting the protocol entirely. ZAP requires the full URL with protocol.


Scan Takes 5+ Minutes <a name="scan-timing>

Be Patient During the Scan

The ZAP baseline scan involves spidering the target application, which can take 5+ minutes depending on the number of pages:

[INFO] Passing the 'view' to the scanner...
[INFO] Passive scan queue size: 0 Passive scan thread limit: 0
[INFO] Acquisition [SPIDER] Complete.

Common mistake: Assuming the scan failed because there's no output for several minutes. ZAP is silent during active scanning.

Fix: Wait for the full scan to complete. The summary line at the end shows all findings:

FAIL-NEW: 0 FAIL-INPROG: 0 WARN-NEW: 17 WARN-INPROG: 0 INFO: 0 IGNORE: 0 PASS: 48

JSON Output with Volume Mount

Saving Scan Results to a File

To save results as JSON, use a volume mount:

docker run --user $(id -u):$(id -g) -w /zap -v $(pwd):/zap/wrk:rw --rm hysnsec/zap:2.16.1 zap-baseline.py -t https://prod-<machine-id>.lab.practical-devsecops.training -J zap-output.json

Flags explained:

Flag Purpose
--user $(id -u):$(id -g) Run as current user for file permissions
-w /zap Working directory inside container
-v $(pwd):/zap/wrk:rw Mount current directory for output
-J zap-output.json Write JSON report

Verify the Output

cat zap-output.json

Common mistake: Forgetting the volume mount. Without -v, the JSON file is created inside the container and is lost when the container exits.


Authenticated Scans

Scanning Protected Areas

For applications that require login, use the context file and user flags:

docker run --rm hysnsec/zap:2.16.1 zap-baseline.py \
  -t https://prod-<machine-id>.lab.practical-devsecops.training \
  -n context-file.json \
  -U username

Key concept: Without authentication, ZAP can only scan publicly accessible pages. Protected endpoints won't be tested.


Scan Result Categories

Understanding the Summary

ZAP classifies findings into these categories:

Category Meaning
FAIL-NEW New high-severity vulnerabilities that should be fixed immediately
FAIL-INPROG Known failures being worked on
WARN-NEW New warnings — should be reviewed
WARN-INPROG Known warnings being monitored
INFO Informational findings
IGNORE Suppressed findings
PASS Checks that passed

Common Warnings

Typical baseline scan results include:

  • Strict-Transport-Security Header Not Set [10035] — HSTS not configured
  • Server Leaks Version Information [10036] — Server header exposes version
  • Permissions Policy Header Not Set [10063] — Feature policy not configured
  • Source Code Disclosure - SQL [10099] — SQL error messages visible

These are warnings, not failures. They indicate areas for improvement.


Machine Timeout and 404 Errors

Two Machines: DevSecOps Box and Production

This exercise uses 2 machines: DevSecOps Box (where you run ZAP) and Production (the target application).

  • 2-hour timeout applies to both machines independently.
  • If the Production machine times out, ZAP scans will fail with connection errors.
  • 404 errors mean the machine was recycled.

Fix: Refresh the exercise page and click Start the Exercise again.


Common Questions

Question Answer
The ZAP scan seems stuck with no output. Normal. Scans take 5+ minutes. Wait for the summary line.
How do I save the scan results to a file? Use -J zap-output.json with a volume mount: -v $(pwd):/zap/wrk:rw.
My target URL returns connection refused. The production application may not be fully started yet. Wait 30 seconds and retry.
Can I adjust how long ZAP spiders the target? Yes, use -m mins (default is 1 minute).
What does WARN-NEW: 17 mean? 17 new warnings were found. These should be reviewed but aren't critical failures.
Do I need to docker pull the ZAP image first? No. docker run auto-pulls if the image isn't present.

Wrap-Up

OWASP ZAP baseline scans are a quick way to find web application security issues. Key takeaways:

  • zap-baseline.py -t <URL> is the core command. The URL must include the protocol (https://).
  • Scans take 5+ minutes — be patient and wait for the summary.
  • JSON output requires a volume mount (-v $(pwd):/zap/wrk:rw) and --user $(id -u):$(id -g).
  • WARN-NEW findings are common and expected for unhardened applications.
  • Two machines are involved (DevSecOps Box + Production), both with 2-hour timeouts.

The DevSecOps Box is stateless — all scan outputs are lost on page refresh.