Add fetchZAPResults.sh script to download ZAP reports from a URL#450
Add fetchZAPResults.sh script to download ZAP reports from a URL#450TheAuditorTool wants to merge 2 commits intoOWASP-Benchmark:masterfrom
Conversation
Adds a shell script that downloads a ZAP XML report from a remote ZAP instance via its REST API and saves it to the results/ directory. This enables scorecard generation when ZAP and Benchmark run in separate Docker containers without a shared filesystem. Closes OWASP-Benchmark#21
utafrali
left a comment
There was a problem hiding this comment.
The script is well-structured and follows existing project conventions, but has one functional bug (missing mkdir -p results/ that will cause a confusing curl failure), a security concern around API key exposure in the process list, and minor best-practice gaps with error output going to stdout.
scripts/fetchZAPResults.sh
Outdated
| output="results/${filename}" | ||
|
|
||
| echo "Downloading ZAP report from: ${zap_url}" | ||
| http_code=$(curl -sS -o "${output}" -w '%{http_code}' --connect-timeout 10 --max-time 120 "${zap_url}") |
There was a problem hiding this comment.
The results/ directory is never created before curl writes to it. If the directory doesn't exist, curl will fail with Failed writing body and then the HTTP status check on line 45 may not behave as expected (the file won't exist for the head -2 check either). Add mkdir -p results/ between lines 40 and 42:
output="results/${filename}"
mkdir -p results/
echo "Downloading ZAP report from: ${zap_url}"
scripts/fetchZAPResults.sh
Outdated
| # | ||
| # Examples: | ||
| # scripts/fetchZAPResults.sh http://172.17.0.3:8090/OTHER/core/other/xmlreport/ | ||
| # scripts/fetchZAPResults.sh "http://zap:8090/OTHER/core/other/xmlreport/?apikey=abc123" |
There was a problem hiding this comment.
Passing ?apikey=abc123 as part of the URL argument exposes the API key in the process list (ps aux or /proc/$PID/cmdline). Consider accepting the key as a separate argument and passing it via curl's -H flag instead:
# scripts/fetchZAPResults.sh <ZAP_REPORT_URL> [OUTPUT_FILENAME] [API_KEY]
if [ -n "${api_key:-}" ]; then
curl_args=(-H "X-ZAP-API-Key: ${api_key}")
fi
curl -sS -o "${output}" -w '%{http_code}' "${curl_args[@]}" ...This keeps the key out of the argument list. The existing ?apikey= query-param form can still be documented as an alternative for ZAP versions that require it in the URL.
scripts/fetchZAPResults.sh
Outdated
| http_code=$(curl -sS -o "${output}" -w '%{http_code}' --connect-timeout 10 --max-time 120 "${zap_url}") | ||
|
|
||
| if [ "${http_code}" -ne 200 ]; then | ||
| echo "ERROR: Download failed with HTTP status ${http_code}" |
There was a problem hiding this comment.
Error messages on lines 46 and 52-54 are written to stdout instead of stderr. Tools and callers typically check stderr for diagnostics. Redirect them:
echo "ERROR: Download failed with HTTP status ${http_code}" >&2and
echo "ERROR: Downloaded file does not appear to be a ZAP XML report." >&2
echo "First 3 lines of downloaded content:" >&2
head -3 "${output}" >&2- Add mkdir -p results/ before curl writes to it (fixes failure on fresh clone) - Pass API key via X-ZAP-API-Key header instead of URL query param (keeps key out of process list and shell history) - Redirect all error/usage output to stderr - Validate getBenchmarkVersion.sh output is non-empty before building filename
Thank you for the review. |
Summary
Closes #21
Adds a shell script (
scripts/fetchZAPResults.sh) that downloads a ZAP XML report from a remote ZAP instance via its REST API and saves it to theresults/directory. This enables scorecard generation when ZAP and Benchmark run in separate Docker containers without a shared filesystem.Motivation
As described in #21, when ZAP runs in one Docker container and the Benchmark app runs in another, there is no shared filesystem to place a ZAP XML report into the
results/directory. This script bridges that gap by fetching the report over HTTP from ZAP's REST API.Usage
The script auto-generates the output filename using the Benchmark version from
pom.xmland the current date (e.g.,Benchmark_1.2-ZAP-20260413.xml), matching the existing naming convention inresults/.What it does
curlis available (via existingrequireCommand.sh)<OWASPZAPReportmarker)results/with a properly formatted filenameresults/stays cleanDesign decisions
curl(likerunSonarQube.sh),requireCommand.sh(likerunBearer.sh,runSemgrep.sh), andgetBenchmarkVersion.sh(likerunBearer.sh,runSemgrep.sh,runCodeQL.sh)createScorecards.sh, matching how every other tool in the project worksresults/and confusing the scorecard generatorWhat is NOT changed
pom.xml/ dependency changessrc/main/java/org/owasp/benchmark/testcode/ZapReaderalready handles the downloaded XML)Test plan
scripts/fetchZAPResults.shwith no arguments -- should print usage and exit 1results/./createScorecards.shafter downloading -- scorecard should include the new ZAP results