rmi-backend/scripts/dast_scan.sh

93 lines
2.9 KiB
Bash
Executable file

#!/usr/bin/env bash
# DAST scan script for RMI — OWASP ZAP quick scan against staging
# Usage: bash scripts/dast_scan.sh [target_url]
# Target defaults to http://localhost:8000
set -euo pipefail
TARGET="${1:-http://localhost:8000}"
REPORT_DIR="/tmp/zap-reports"
TIMESTAMP="$(date +%Y%m%d-%H%M%S)"
REPORT="$REPORT_DIR/zap-report-$TIMESTAMP.json"
log() { echo "[$(date +%H:%M:%S)] $*"; }
log "=== DAST Scan: $TARGET ==="
log "Timestamp: $TIMESTAMP"
# Create output directory
mkdir -p "$REPORT_DIR"
# Check if ZAP is installed
if ! command -v zap-cli &>/dev/null && ! command -v zap.sh &>/dev/null; then
log "ZAP not installed. Running with OWASP ZAP Docker image..."
if ! docker image inspect zaproxy/zap-stable &>/dev/null 2>&1; then
log "Pulling ZAP Docker image (first run)..."
docker pull zaproxy/zap-stable
fi
# Run ZAP in Docker
docker run --rm --network="host" zaproxy/zap-stable \
zap-baseline.py \
-t "$TARGET" \
-J "$REPORT" \
-a \
-r "${REPORT%.json}.html" \
2>&1 | tee -a "$REPORT_DIR/zap-output-$TIMESTAMP.log" || true
elif command -v zap-cli &>/dev/null; then
log "Using ZAP CLI..."
# Start ZAP daemon (if not running)
zap-cli --zap-url http://localhost:8090 status || {
log "Starting ZAP daemon..."
zap start -p 8090 &>/dev/null
sleep 5
}
# Run spider (crawl)
log "Spidering $TARGET..."
zap-cli --zap-url http://localhost:8090 spider "$TARGET"
# Run active scan
log "Scanning $TARGET..."
zap-cli --zap-url http://localhost:8090 quick-scan "$TARGET" \
--spider --scanners all
# Export report
log "Generating report..."
zap-cli --zap-url http://localhost:8090 report -o "$REPORT" -f json
fi
# Parse results
log "=== Results ==="
if [ -f "$REPORT" ]; then
# Count findings by severity
if command -v jq &>/dev/null; then
HIGHS=$(jq --raw-output '[.site[].alerts[] | select(.riskcode=="3")] | length' "$REPORT" 2>/dev/null || echo "0")
MEDIUMS=$(jq --raw-output '[.site[].alerts[] | select(.riskcode=="2")] | length' "$REPORT" 2>/dev/null || echo "0")
LOWS=$(jq --raw-output '[.site[].alerts[] | select(.riskcode=="1")] | length' "$REPORT" 2>/dev/null || echo "0")
INFOS=$(jq --raw-output '[.site[].alerts[] | select(.riskcode=="0")] | length' "$REPORT" 2>/dev/null || echo "0")
log "High: $HIGHS"
log "Medium: $MEDIUMS"
log "Low: $LOWS"
log "Info: $INFOS"
else
log "Report saved (jq not installed for summary): $REPORT"
fi
# Gate: fail on high-severity
if [ "${HIGHS:-0}" -gt 0 ]; then
log "FAIL: $HIGHS high-severity vulnerabilities found!"
log "Review: $REPORT"
exit 1
fi
log "PASS: No high-severity vulnerabilities"
else
log "WARN: No report file generated"
fi
log "Full report: ${REPORT}"
log "=== DAST scan complete ==="