OWASP ZAP: Complete Guide to Web Application Security Testing Using Kali Linux

OWASP ZAP: Complete Guide to Web Application Security Testing Using Kali Linux

OWASP Zed Attack Proxy (ZAP) is a free, open-source web application security scanner maintained under the OWASP (Open Web Application Security Project) umbrella, now stewarded by the Zaproxy team. It functions similarly to Burp Suite — as an intercepting proxy — but is fully open source, making it a popular choice for organizations that cannot license Burp Professional. ZAP supports both a full desktop GUI and a headless/daemon mode with a REST API, making it well suited for CI/CD pipeline integration. Core capabilities include automated spidering, AJAX spidering (for JavaScript-heavy apps), active and passive scanning, fuzzing, and a scripting console supporting multiple languages.

How to Install

# Kali Linux - preinstalled, but to install/update:
sudo apt update
sudo apt install zaproxy -y

# Verify installation
zaproxy -version

Alternative: install via the official cross-platform installer or Docker:

# Docker (stable release)
docker pull zaproxy/zap-stable
docker run -it zaproxy/zap-stable zap-baseline.py -t https://example.com

Snap package (Ubuntu/Debian derivatives):

sudo snap install zaproxy --classic

Syntax

zap.sh [options]
zap-baseline.py -t <target_url> [options]
zap-full-scan.py -t <target_url> [options]
zap-api-scan.py -t <api_definition_url> [options]

All Command-Line Options

GUI/daemon launcher (zap.sh):

OptionDescription
-daemonRun ZAP as a background daemon (no GUI)
-port <port>Set the proxy/API port (default 8080)
-host <host>Bind ZAP to a specific host/interface
-config <key=value>Set a configuration parameter (e.g., API key)
-dir <path>Set the ZAP home directory
-cmdRun in command-line mode
-quickurl <url>Quickly scan a single URL
-quickout <path>Output path for quick scan report

Docker automation scripts:

ScriptPurpose
zap-baseline.pyPassive scan only, spiders briefly, safe for production
zap-full-scan.pyFull active + passive scan, more intrusive
zap-api-scan.pyScans REST/SOAP/GraphQL APIs from a definition file

Common flags for automation scripts:

FlagDescription
-t <url>Target URL
-r <file>Output HTML report filename
-J <file>Output JSON report filename
-x <file>Output XML report filename
-m <minutes>Max spider time in minutes
-T <minutes>Max overall scan time
-aInclude the ajax spider
-dShow debug messages
-IDo not return failure on warnings
-jUse ajax spider instead of traditional spider
-z <options>Pass raw ZAP options string

Basic Usage (Expected Output in Bash)

$ zap.sh -daemon -port 8090 -config api.disablekey=true

Output:

[main] INFO  org.zaproxy.zap.ZAP - Loading configuration...
[main] INFO  org.zaproxy.zap.ZAP - ZAP is now listening on 0.0.0.0:8090
OWASP ZAP 2.15.0 started as daemon

Practical Examples with Output

Example 1 — Baseline passive scan via Docker

$ docker run --rm -t zaproxy/zap-stable zap-baseline.py -t https://example.com

Output:

PASS: Absence of Anti-CSRF Tokens (10202)
WARN: X-Content-Type-Options Header Missing (10021) x 3
WARN: Server Leaks Version Information (10036) x 1
FAIL-NEW: 0    FAIL-INPROG: 0    WARN-NEW: 2    WARN-INPROG: 0

Example 2 — Full active scan with HTML report

$ zap-full-scan.py -t https://testphp.vulnweb.com -r zap-full-report.html

Output:

Total of 47 URLs
PASS: SQL Injection (40018)
FAIL-NEW: 1    Cross Site Scripting (Reflected) (40012)
Report saved to zap-full-report.html

Example 3 — Start daemon and access via REST API

$ zap.sh -daemon -port 8090 -config api.key=abc123 &
$ curl "http://localhost:8090/JSON/core/view/version/?apikey=abc123"

Output:

{"version":"2.15.0"}

Example 4 — Trigger a spider scan via API

$ curl "http://localhost:8090/JSON/spider/action/scan/?apikey=abc123&url=https://example.com"

Output:

{"scan":"0"}

Example 5 — Check spider scan progress

$ curl "http://localhost:8090/JSON/spider/view/status/?apikey=abc123&scanId=0"

Output:

{"status":"45"}

Example 6 — Retrieve discovered URLs

$ curl "http://localhost:8090/JSON/spider/view/results/?apikey=abc123&scanId=0" | jq .

Output:

{"results":["https://example.com/","https://example.com/login","https://example.com/about"]}

Example 7 — Run active scan via API

$ curl "http://localhost:8090/JSON/ascan/action/scan/?apikey=abc123&url=https://example.com&recurse=true"

Output:

{"scan":"1"}

Example 8 — Generate JSON report from CLI

$ zap-baseline.py -t https://example.com -J zap-report.json
$ cat zap-report.json | jq '.site[0].alerts | length'

Output:

7

Example 9 — Scan an OpenAPI/Swagger definition

$ zap-api-scan.py -t https://api.example.com/openapi.json -f openapi -r api-report.html

Output:

Importing OpenAPI definition from https://api.example.com/openapi.json
PASS: Format String Error (90020)
WARN-NEW: 1    Missing Anti-clickjacking Header (10020)
Report saved to api-report.html

7. Common Use Cases

  • CI/CD pipeline DAST scanning of staging environments using zap-baseline.py.
  • Full manual and automated web application penetration testing via the ZAP desktop GUI.
  • REST/SOAP/GraphQL API security testing with zap-api-scan.py.
  • Ad-hoc quick scanning of a single URL for a fast risk snapshot.
  • Scripted regression security testing integrated into Jenkins/GitLab CI pipelines.

Automation with Bash

#!/bin/bash
# zap-ci-scan.sh — run a ZAP baseline scan in CI and fail the build on high-risk findings

TARGET="$1"
REPORT="zap-report-$(date +%Y%m%d-%H%M%S).html"

if [ -z "$TARGET" ]; then
    echo "Usage: $0 <target_url>"
    exit 1
fi

docker run --rm -v "$(pwd):/zap/wrk/:rw" -t zaproxy/zap-stable \
    zap-baseline.py -t "$TARGET" -r "$REPORT" -I

EXIT_CODE=$?

if [ $EXIT_CODE -eq 0 ]; then
    echo "[+] No blocking issues found. Report: $REPORT"
else
    echo "[!] ZAP found issues. Review $REPORT before deploying."
fi

exit $EXIT_CODE

9. Tips and Best Practices

  • Use zap-baseline.py for production/staging environments (non-intrusive); reserve zap-full-scan.py for isolated test environments.
  • Always set an API key (api.key=...) when exposing the daemon’s REST API beyond localhost.
  • Use the AJAX Spider (-j) for Single Page Applications (React/Angular/Vue) since the traditional spider cannot execute JavaScript.
  • Authenticate ZAP sessions (via Context + Authentication scripts) before scanning pages behind login to get meaningful coverage.
  • Exclude logout URLs from scope to avoid the scanner invalidating its own session mid-scan.

Troubleshooting

IssueCauseFix
Unauthorized API responsesMissing/incorrect API keyPass apikey= param matching -config api.key=
Spider finds 0 URLs on SPAJavaScript-rendered content not crawledUse AJAX Spider (-j flag or ajaxSpider API)
Docker scan can’t reach target on localhostContainer network isolationUse --network=host or the target’s routable IP, not localhost
Scan takes extremely longNo time limit setUse -m and -T flags to cap spider/scan duration
Report file not createdVolume not mounted in DockerMount working dir with -v $(pwd):/zap/wrk/:rw

References

  • Official site: https://www.zaproxy.org/
  • Documentation: https://www.zaproxy.org/docs/
  • Docker automation guide: https://www.zaproxy.org/docs/docker/
  • Kali tool page: https://www.kali.org/tools/zaproxy/
Total
0
Shares

Leave a Reply

Previous Post
Kubescape: Complete Guide to Kubernetes Security Scanning and Compliance Assessment Using Kali Linux

Kubescape: Complete Guide to Kubernetes Security Scanning and Compliance Assessment Using Kali Linux

Next Post
Wappalyzer CLI: Complete Guide to Web Technology Fingerprinting and Stack Detection Using Kali Linux

Wappalyzer CLI: Complete Guide to Web Technology Fingerprinting and Stack Detection Using Kali Linux

Related Posts