Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Zed Attack Proxy: Why JSON Report Fails in Python?

Troubleshooting Zed Attack Proxy JSON report failure using Python and Podman on Windows. Fix path issues and generate valid ZAP reports.
Frustrated developer looking at ZAP JSON report error in terminal while using Python and Podman Frustrated developer looking at ZAP JSON report error in terminal while using Python and Podman
  • ⚠️ Zed Attack Proxy JSON report failures often come from missing volume mounts or improperly translated Windows paths.
  • 🧠 Installing the "reporting" add-on is needed for JSON output in ZAP.
  • 📝 Python scripts must wait for the container to finish and handle output using subprocess tools.
  • 📁 Podman on Windows expects paths in WSL/Linux format like /mnt/c/ for volume mounts to work.
  • 🔍 Parsing and using JSON reports with Python makes it possible to fully integrate into DevSecOps pipelines.

If you’ve tried automating your Zed Attack Proxy (ZAP) scans using a Python script within Podman on a Windows machine—only to be confused by a failed JSON report or a missing output—you’re not alone. This guide looks at all the important technical details, from container volume mounts to Python subprocess handling and ZAP command structure. It helps you get dependable JSON report generation for your DevSecOps work.


Zed Attack Proxy in Dev Automation

Zed Attack Proxy (ZAP), developed and maintained by the OWASP Foundation, is one of the most powerful and popular open-source web application security scanners available today. It finds security vulnerabilities in active development. ZAP is a key tool in any DevSecOps pipeline. Teams across the globe use ZAP both interactively and in automated CI/CD environments to always check how secure web applications are.

For automation, ZAP supports several interfaces:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  • Command-Line Interface (CLI): For quick scans and scripted automation.
  • Daemon/API Mode: For programmatic interaction using supported clients including Python and Java.
  • Web UI: Mainly for manual scanning and manual testing.

Among various output formats, the JSON report is very useful for putting results into existing monitoring systems, custom dashboards, data pipelines, and incident management tools.

Automating scans and processing output using a Python script is common. But when you use Podman as your container runtime—and Windows as your host OS—things get tricky quickly. This happens because of path translation issues, permissions, and the need for correct ways to map output from the container to the host.


The Dev Scenario: ZAP + Python + Podman on Windows

Let's look at a common developer task: you're on a Windows 10 or 11 workstation. You're writing a Python script to automate a ZAP scan against your staging application. The ZAP image runs in a container with Podman. Your plan is to run things this way:

  1. Launch a Podman container running OWASP ZAP.
  2. Point ZAP to a target URL.
  3. Trigger a quick scan.
  4. Save a report in JSON format to a known output directory on the Windows host.
  5. Exit the container.

Money in the bank—until this shows up:

"Job report failed to generate report"

Or worse:

  • No report at all.
  • The container exits with success but writes… nothing.
  • The Python script shows no error, but your output folder is empty.

This is the mix of odd path mapping and command order problems in container scans on non-Linux systems.


How ZAP Generates Reports

ZAP can generate reports using its internal way of making reports. You can start it with:

  1. The CLI using zap.sh
  2. The ZAP API via JSON-RPC or RESTful endpoints

For CLI-based use, the ZAP image has simple flags like:

zap.sh -cmd -quickurl http://app-under-test.com \
       -addoninstall reporting \
       -quickout /zap/wrk/output.json \
       -quickprogress

Breaking it down:

  • -cmd: Run in command-line mode (headless).
  • -quickurl: The target URL to scan.
  • -addoninstall: Adds needed plugins like “reporting” when needed.
  • -quickout: Path where the report (JSON, in this case) is written.
  • -quickprogress: Shows progress feedback.

The /zap/wrk directory inside the container is where output files, session data, and logs are usually written. Unless mapped to a directory on your Windows host using a correct volume mount, anything written there stays only inside the container while it is running—and is deleted when --rm is used.


Python Script: Launching ZAP from Code

A Python script using subprocess.run (or subprocess.Popen) gives you a way to start and manage container processes from your automation code. When doing this with ZAP’s CLI inside Podman, you might write:

import subprocess

subprocess.run([
    "podman", "run", "--rm",
    "owasp/zap2docker-stable",
    "zap.sh", "-cmd",
    "-quickurl", "http://target-site.com",
    "-addoninstall", "reporting",
    "-quickout", "/zap/wrk/report.json"
])

While this seems right, it fails silently or outputs unclear error logs under several wrong setups:

  • Missing a volume mount, so /zap/wrk cannot be reached from the host.
  • Windows-native paths like C:\Users\MyName aren’t translated into mounts that containers can use.
  • The "reporting" addon is not yet installed, so ZAP can't make a JSON report.
  • The Python script exits before the scan completes because subprocess.run() isn’t set up to show stdout/stderr messages.
  • Not enough write permissions to the mounted output path.

Why the JSON Report Fails

Let’s go deeper into the main reasons it fails:

  • No Volume Mount Defined
    Without -v or --volume, the output stays within the container and is lost when the container exits.

  • Improper Windows Path Format
    Podman on Windows expects paths using Linux notation (e.g., /mnt/c/Users/...) instead of C:\Users\....

  • Missing Required Add-ons
    The JSON report function needs the "reporting" plugin. Not specifying -addoninstall reporting results in an unsupported command error or empty response.

  • Permissions
    Even if the directory appears to exist, Podman may not have write access unless it’s clearly given or mounted using the correct permissions.

  • Scan Not Done on Time
    If the Python script doesn’t monitor or wait for scan completion and immediately tries to access an unfinished or not there output file, the report will appear missing.


Fixing the Setup Step-by-Step

Let’s walk through a good way to set things up and find problems:

1. Add Verbose Logging

Add flags to see more:

-quickprogress -config api.disablekey=true

This helps debug internal steps and find scan or report errors.

2. Install Required Add-ons

ZAP needs the reporting add-on:

-addonupdate -addoninstall reporting

3. Proper Volume Mounts

Map local directory using:

-v /mnt/c/dev/zap-output:/zap/wrk

✅ Path must:

  • Exist before running the command.
  • Be writeable by the container.
  • Be expressed in WSL-compatible syntax.

4. Normalize Windows Paths

Do NOT use C:\Users\xyz in -v; instead translate to:

/mnt/c/Users/xyz/folder

You can find WSL paths by running wsl and navigating to your Windows folders from there.

5. Use Subprocess Properly

Collect all process outputs:

result = subprocess.run([...], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(result.stdout.decode())
print(result.stderr.decode())

This output can show plugin load errors, permissions issues, or scan interruptions.


Paths and Volumes with Podman on Windows

Podman is a rootless container engine not linked to the Docker daemon. This adds more ways to do things, especially in business settings. But it makes path translation harder when running under Windows environments.

📍 Key notes:

  • Always use Linux-style paths (/mnt/c/...).
  • Paths must exist before mapping, or Podman may silently fail.
  • Use the --mount or -v flags for two-way persistence.
  • Consider testing volume mappings with dummy containers like alpine ls /zap/wrk.

Incorrect volume mounts are the number one cause for “JSON files that seem to appear but are not there.”


Proper Python Script for ZAP Execution

Here’s a better and working Python script for running a ZAP scan and making a dependable JSON report:

import subprocess
import shlex
import os

output_dir = "/mnt/c/dev/zap-results"
os.makedirs(output_dir, exist_ok=True)  # Ensure output directory exists

cmd = f"""
podman run --rm
-v {output_dir}:/zap/wrk
owasp/zap2docker-stable
zap.sh -cmd
-addonupdate
-addoninstall reporting
-quickurl http://example.com
-quickout /zap/wrk/report.json
-quickprogress
"""

# Use shlex to properly parse the command
proc = subprocess.run(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE)

# Output logs for debugging
print("STDOUT:\n", proc.stdout.decode())
print("STDERR:\n", proc.stderr.decode())

# Check existence of the report
report_path = os.path.join("C:/dev/zap-results", "report.json")
if os.path.exists(report_path):
    print("✅ Report generated:", report_path)
else:
    print("❌ Report not found. Check container logs.")

Make sure:

  • Podman is installed and integrated with WSL.
  • The target folder is not locked by another process.
  • Port conflicts or proxy software on Windows aren’t interfering with container networking.

Confirming and Parsing JSON Output in Python

Here’s how you can easily check and use the ZAP output:

import json

with open("C:/dev/zap-results/report.json") as f:
    zap_report = json.load(f)

# Print summaries
for site in zap_report.get("site", []):
    print("Scanned Site:", site.get("name"))
    for alert in site.get("alerts", []):
        print(f"- [{alert['risk']}]: {alert['alert']}")

This level of automation lets you:

  • Integrate findings into Slack or email alerts
  • Trigger ticket creation
  • Display web dashboards or CI job summaries

Best Practices for Reliable Automation

  • ✅ Use tagged container images like zap2docker-stable:2.12.0 for builds you can repeat.
  • ✅ Keep output directories clean and checked before each scan.
  • ✅ Use -addonupdate to make sure it works with the reporting plugin.
  • ✅ Log all scan results (stdout/stderr) using Python so you have a record.
  • ✅ Avoid running sensitive reports without encryption on exposed volumes.

ZAP API as an Alternative Option

For more complex tasks, the official ZAP Python API client (python-owasp-zap-v2) offers much more control:

Benefits:

  • Connect to a running daemon
  • Queue scans and monitor progress
  • Fetch structured results directly via JSON
  • Avoid filesystem write issues altogether

Example:

from zapv2 import ZAPv2

zap = ZAPv2(apikey='', proxies={'http': 'http://localhost:8080'})
zap.urlopen('http://example.com')
scan_id = zap.ascan.scan('http://example.com')
print('Scan started. ID:', scan_id)

But for single scans or CI environments, a CLI-based subprocess model as shown above is often simpler, faster, and good enough for many dev teams.


When It's More Than Just the Report

More complex problems may require more detailed debugging:

  • JVM errors: Use -daemon mode to check for logs.
  • DNS/network: Check if it can connect inside the container (ping, curl).
  • Container corruption: Rebuild local images or re-pull from source.

You can also:

  • Check /zap/zap.log inside the container.
  • Manually step through a scan interactively to see what happens.
  • Join the OWASP ZAP community forums for help or to report bugs.

Wrapping It All Up

JSON report failures when using Zed Attack Proxy with Python and Podman on Windows are usually because of mount path issues, missing plugins, or scan interruptions. But with correctly mapped Linux-style paths, needed add-ons installed, and careful subprocess handling, you can fully automate dependable ZAP scans. Whether in local scripts or CI/CD pipelines, structured ZAP reports can help teams use real-time security information—efficiently and again and again.


References

OWASP. (2023). ZAP User Manual. Retrieved from https://owasp.org/www-project-zap

Podman.io. (2023). Windows Support: Path Mapping and Volume Mounts. Retrieved from https://podman.io/getting-started/windows

Python.org. (n.d.). subprocess — Subprocess management in Python. Retrieved from https://docs.python.org/3/library/subprocess.html

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading