101 lines
3.1 KiB
Bash
101 lines
3.1 KiB
Bash
#!/bin/bash
|
|
# ============================================================
|
|
# Script OWASP ZAP — SaaS Turf Prédictions IA
|
|
# Sprint 8 — QA, Beta Fermee, Go/No-Go
|
|
# Ticket: HRT-34
|
|
#
|
|
# Prérequis : Docker, APP en cours d'exécution
|
|
# Usage : bash tests/security/run_owasp_zap.sh [APP_URL]
|
|
# ============================================================
|
|
|
|
set -e
|
|
|
|
APP_URL="${1:-http://localhost:8792}"
|
|
REPORT_DIR="tests/reports"
|
|
ZAP_IMAGE="ghcr.io/zaproxy/zaproxy:stable"
|
|
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
|
|
|
mkdir -p "$REPORT_DIR"
|
|
|
|
echo "============================================================"
|
|
echo "OWASP ZAP — Scan SaaS Turf IA"
|
|
echo "Target : $APP_URL"
|
|
echo "============================================================"
|
|
|
|
# Vérifier que Docker est disponible
|
|
if ! command -v docker &>/dev/null; then
|
|
echo "❌ Docker non disponible. Installer Docker pour exécuter OWASP ZAP."
|
|
exit 1
|
|
fi
|
|
|
|
# Vérifier que l'app est en cours d'exécution
|
|
if ! curl -sf "$APP_URL" >/dev/null 2>&1; then
|
|
echo "❌ App non accessible sur $APP_URL"
|
|
echo " Démarrer l'application avant de lancer le scan."
|
|
exit 1
|
|
fi
|
|
|
|
echo "✅ App accessible sur $APP_URL"
|
|
echo ""
|
|
echo "Démarrage du scan OWASP ZAP (mode baseline)..."
|
|
|
|
# Scan ZAP en mode baseline (rapide, non-destructif)
|
|
docker run --rm \
|
|
--network host \
|
|
-v "$(pwd)/tests/reports:/zap/wrk:rw" \
|
|
"$ZAP_IMAGE" \
|
|
zap-baseline.py \
|
|
-t "$APP_URL" \
|
|
-r "zap_report_${TIMESTAMP}.html" \
|
|
-J "zap_report_${TIMESTAMP}.json" \
|
|
-l WARN \
|
|
2>&1 | tee "$REPORT_DIR/zap_output_${TIMESTAMP}.log"
|
|
|
|
ZAP_EXIT=$?
|
|
|
|
# Analyser le rapport JSON
|
|
REPORT_JSON="$REPORT_DIR/zap_report_${TIMESTAMP}.json"
|
|
if [ -f "$REPORT_JSON" ]; then
|
|
CRITICAL=$(python3 -c "
|
|
import json, sys
|
|
try:
|
|
data = json.load(open('$REPORT_JSON'))
|
|
alerts = data.get('site', [{}])[0].get('alerts', [])
|
|
critical = [a for a in alerts if a.get('riskcode', '0') == '3']
|
|
high = [a for a in alerts if a.get('riskcode', '0') == '2']
|
|
print(f'CRITICAL:{len(critical)},HIGH:{len(high)}')
|
|
for a in critical:
|
|
print(f' [CRITICAL] {a.get(\"alert\", \"?\")}')
|
|
for a in high:
|
|
print(f' [HIGH] {a.get(\"alert\", \"?\")}')
|
|
except Exception as e:
|
|
print(f'CRITICAL:?,HIGH:? (parse error: {e})')
|
|
" 2>/dev/null || echo "CRITICAL:?,HIGH:?")
|
|
|
|
echo ""
|
|
echo "============================================================"
|
|
echo "RÉSULTATS OWASP ZAP"
|
|
echo "============================================================"
|
|
echo "$CRITICAL"
|
|
|
|
CRIT_COUNT=$(echo "$CRITICAL" | head -1 | cut -d: -f2 | cut -d, -f1)
|
|
if [ "$CRIT_COUNT" = "0" ]; then
|
|
echo ""
|
|
echo "✅ PASS — Zéro vulnérabilité critique"
|
|
else
|
|
echo ""
|
|
echo "❌ FAIL — $CRIT_COUNT vulnérabilité(s) critique(s) détectée(s)"
|
|
echo " Action requise avant Go/No-Go"
|
|
fi
|
|
else
|
|
echo "⚠️ Rapport JSON non généré"
|
|
fi
|
|
|
|
echo ""
|
|
echo "Rapport HTML : $REPORT_DIR/zap_report_${TIMESTAMP}.html"
|
|
echo "Rapport JSON : $REPORT_DIR/zap_report_${TIMESTAMP}.json"
|
|
echo "Log complet : $REPORT_DIR/zap_output_${TIMESTAMP}.log"
|
|
echo "============================================================"
|
|
|
|
exit $ZAP_EXIT
|