Files
tessera-ctl/.gitea/scripts/zap-hooks.py
T
schalli bf632d90a5 fix(quick-261009-p0m): Review-Befunde WR-01/02/04/05, IN-01/02/03/04 (Abbild-Bau, Semgrep im Container, Zeitbudget, ZAP-Haken)
- WR-01: prisma generate als eigener Schritt mit Pruefung im api-Abbild, Bau scheitert ohne Client; Startprobe als .gitea/scripts/image-start-check.sh versioniert
- WR-02: Semgrep im offiziellen Container, per Digest angepinnt (kein pipx/PyPI mehr)
- WR-04: Zeitbudget 1500 s, Limits je Werkzeug, Ergebniszeile sofort nach jedem Werkzeug
- WR-05: Authorization-Ersetzung der ZAP-Pruefung nur fuer das Ziel
- IN-01: yarn/npm per Platzhalter entfernt und Abwesenheit geprueft (api und web)
- IN-02: Kommentar zu doppelten Kopfzeilen in next.config.ts richtiggestellt
- IN-03: Berichtsordner Modus 700, Zugangsdaten nur als base64 (keine curl-Konfiguration)
- IN-04: flacher Klon wird bei gitleaks als unvollstaendig gemeldet

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-09 20:59:12 +02:00

41 lines
1.7 KiB
Python

"""zap-hooks.py -- Haken fuer die ZAP-Grundpruefung (quick-261009-p0m).
Wird von .gitea/scripts/zap-baseline.sh schreibgeschuetzt in den ZAP-Container
eingebunden und mit `--hook=` geladen. Nur Standardbibliothek.
Aufgaben:
1. Die klassische Spinne soll Formulare weder ausfuellen noch absenden. So bleibt
die Pruefung rein passiv: es werden nur Seiten abgerufen (GET), nie Daten
an die Anwendung geschickt (kein POST).
2. Nur wenn die Umgebungsvariable ZAP_BASIC_AUTH gesetzt ist (Anmeldedatei-Weg des
Skripts), wird eine Ersetzungsregel fuer den Kopf Authorization eingetragen --
beschraenkt auf Adressen des Ziels (Schema, Host, Port). Andere Hosts (Weiterleitungen,
eingebundene Fremdseiten, Zusatzdienste von ZAP) bekommen den Kopf nie.
Der Wert steht nie in einem Aufruf oder einer Ausgabe.
"""
import os
import re
def zap_started(zap, target):
# Keine Formulare verarbeiten, keine Formulare absenden.
zap.spider.set_option_process_form(False)
zap.spider.set_option_post_form(False)
auth = os.environ.get("ZAP_BASIC_AUTH")
if auth:
# Die Regel gilt nur fuer URLs, die mit der Ziel-Adresse beginnen (Java-Regex, die
# ganze URL muss passen). Danach darf nur ein Pfad, eine Abfrage oder ein Anker
# folgen -- so passt auch http://host:30001 nicht auf das Ziel http://host:3000.
url_regex = re.escape(target.rstrip("/")) + r"(?:[/?#].*)?"
zap.replacer.add_rule(
description="basicauth",
enabled=True,
matchtype="REQ_HEADER",
matchstring="Authorization",
matchregex=False,
replacement=auth,
initiators="",
url=url_regex,
)