docs(quick-261009-p0m): Review-Befunde im Sicherheitsprotokoll und in den Anleitungen nachgetragen
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+42
-12
@@ -274,7 +274,8 @@ nie verzoegert oder verhindert. Er laeuft nur auf `main` und bei Tags `v*`; die
|
||||
Bedingung steht ausdruecklich am Job, weil ein uebersprungenes `needs` in Gitea nicht
|
||||
blockiert (sonst liefe er auch nach einem Push auf `live`). Er hat `continue-on-error`,
|
||||
ein Zeitlimit von 30 Minuten (ein haengender Scan haelt den einzigen Runner nicht fest)
|
||||
und kein Secret. Alles steckt in einem Skript, das auch lokal laeuft:
|
||||
und kein Secret. Das Skript haelt sich selbst an ein Zeitbudget von 25 Minuten (siehe
|
||||
"Zeitbudget" unten). Alles steckt in einem Skript, das auch lokal laeuft:
|
||||
|
||||
```bash
|
||||
GITHUB_REF=refs/heads/main sh .gitea/scripts/security-scan.sh --print-plan # ohne Netz
|
||||
@@ -293,15 +294,25 @@ temporaeren Ordner, gitleaks nur die Git-Historie. Es wird also genau der eingec
|
||||
Stand geprueft; nicht eingecheckte Dateien eines Arbeitsordners erreichen nie ein
|
||||
Werkzeug, einen Bericht oder ein Artefakt.
|
||||
|
||||
**Angepinnte Werkzeuge:** gitleaks 8.30.1, Trivy 0.75.0, osv-scanner 2.6.0, Semgrep 1.180.0
|
||||
(`pipx`), pnpm 9.15.0. Die drei Programme werden von der offiziellen
|
||||
**Angepinnte Werkzeuge:** gitleaks 8.30.1, Trivy 0.75.0, osv-scanner 2.6.0, Semgrep 1.180.0,
|
||||
pnpm 9.15.0. Die drei Programme werden von der offiziellen
|
||||
GitHub-Veroeffentlichung geladen und vor jeder Benutzung gegen eine SHA256-Summe im Skript
|
||||
geprueft (auch das zwischengespeicherte Archiv); stimmt die Summe nicht oder fehlt das
|
||||
Netz, wird nur dieses Werkzeug uebersprungen. Marktplatz-Aktionen fuer Scanner werden
|
||||
Netz, wird nur dieses Werkzeug uebersprungen. **Semgrep** laeuft als Container aus dem
|
||||
offiziellen Abbild `semgrep/semgrep`, angepinnt per Digest (`SEMGREP_IMAGE` im Skript):
|
||||
Docker prueft beim Laden, dass der Inhalt zum Digest passt. Es gibt bewusst keine
|
||||
Installation ueber `pipx`/PyPI mehr -- deren frei aufgeloeste Abhaengigkeiten liefen sonst
|
||||
in einem Job, der den Docker-Socket des Hosts sieht. Der Quellstand geht per `docker cp`
|
||||
in den Container und der Bericht per `docker cp` zurueck (kein Ordner-Mount, denn der
|
||||
Arbeitsordner liegt im Job-Container und nicht auf dem Docker-Rechner). Das Abbild belegt
|
||||
rund 1,5 GB im Docker-Daemon des Runners und bleibt dort zwischengespeichert; ohne Docker
|
||||
wird Semgrep mit `kein-docker` uebersprungen. Marktplatz-Aktionen fuer Scanner werden
|
||||
bewusst nicht benutzt (veraenderliche Etiketten). **Version anheben:** im Kopf von
|
||||
`security-scan.sh` die Version, die URL und die SHA256-Summe aus der offiziellen
|
||||
Pruefsummendatei der Veroeffentlichung gemeinsam austauschen und einmal lokal
|
||||
`sh .gitea/scripts/security-scan.sh all` laufen lassen. Werkzeuge und die Trivy-Datenbank
|
||||
`sh .gitea/scripts/security-scan.sh all` laufen lassen. Bei Semgrep stattdessen
|
||||
`SEMGREP_VERSION` und den Digest in `SEMGREP_IMAGE` tauschen (den Digest zeigt
|
||||
`docker pull semgrep/semgrep:<Version>` in der Zeile `Digest:`). Werkzeuge und die Trivy-Datenbank
|
||||
liegen im persistenten Zwischenspeicher des Runners (`/opt/hostedtoolcache/tessera-security`);
|
||||
der Layer-Zwischenspeicher von Trivy wird nach jedem Lauf geloescht, damit die Platte nicht
|
||||
vollaeuft.
|
||||
@@ -311,13 +322,30 @@ Zertifikatsmanagers, Schluessel-Ausschnitte in Tests und Notizen) und `.semgrepi
|
||||
(Tests, Testdaten, Planungsnotizen). Ein neuer Treffer wird nie vorsorglich freigegeben,
|
||||
sondern erst geprueft.
|
||||
|
||||
**Zeitbudget:** Der Job hat 30 Minuten (`timeout-minutes`). Das Skript rechnet mit einem
|
||||
Gesamtbudget von 1500 Sekunden (25 Minuten) und jedes Werkzeug hat ein eigenes Limit
|
||||
(Variablen `T_*` im Kopf des Skripts): Laden der drei Programme je 60 s, Semgrep-Abbild laden
|
||||
150 s, pnpm 45 s, gitleaks 180 s, `pnpm audit` 90 s, osv-scanner 120 s, Semgrep 300 s, Trivy ueber
|
||||
den Quellstand 180 s, je Abbild 120 s -- zusammen hoechstens 1485 Sekunden. Zusaetzlich kuerzt das
|
||||
Skript jedes Limit auf die noch verbleibende Gesamtzeit; ist nichts mehr uebrig, werden die
|
||||
restlichen Werkzeuge mit `skipped reason=gesamtbudget` gemeldet. Ein Werkzeug, das sein
|
||||
Limit reisst, erscheint als `skipped reason=zeitgrenze`. Die fuenf Minuten Reserve bis zu den
|
||||
30 Minuten decken Checkout und Artefakt-Schritt ab. **Jedes Werkzeug gibt seine Zeile aus,
|
||||
sobald es fertig ist** -- bricht der Runner den Job trotzdem einmal ab, stehen die bis dahin
|
||||
fertigen Ergebnisse im Protokoll.
|
||||
|
||||
**Wo man das Ergebnis sieht:** Im Protokoll des Jobs stehen je Werkzeug eine Zeile
|
||||
`SECURITY-SUMMARY ...` (nur Zahlen) und am Ende `SECURITY-SUMMARY fertig (nur Bericht,
|
||||
Exit 0)`; dieselben Zeilen stehen in `summary.txt`. Die Rohberichte (JSON) haengen,
|
||||
`SECURITY-SUMMARY ...` (nur Zahlen), die Zeile `SECURITY-SUMMARY dauer=...` und am Ende
|
||||
`SECURITY-SUMMARY fertig (nur Bericht, Exit 0)`; dieselben Zeilen stehen in `summary.txt`.
|
||||
Prueft das Skript in einem flachen Klon (ohne volle Historie), steht bei gitleaks
|
||||
`unvollstaendig (flacher Klon ...)` -- dann ist das Ergebnis nicht "sauber", sondern nur fuer die sichtbaren
|
||||
Commits gueltig (die Pipeline holt mit `fetch-depth: 0` immer die volle Historie). Die Rohberichte (JSON) haengen,
|
||||
soweit der Runner es zulaesst, als Artefakt `sicherheitsberichte` (30 Tage) am Lauf. Das
|
||||
Artefakt ist nur "best effort" (Gitea lehnt `upload-artifact@v4` ab, es laeuft `@v3`);
|
||||
verlassen Sie sich auf die Zeilen im Protokoll. Der Job braucht ungefaehr fuenf bis acht
|
||||
Minuten nach `publish`.
|
||||
verlassen Sie sich auf die Zeilen im Protokoll. Der Job braucht auf dem
|
||||
Entwicklungsrechner mit warmem Zwischenspeicher etwa eine Minute; beim allerersten Lauf auf einem
|
||||
frischen Runner kommen das Laden der Programme und des Semgrep-Abbilds (rund 1,5 GB) und die
|
||||
Trivy-Datenbank dazu. Mehr als 25 Minuten laufen nie (siehe "Zeitbudget").
|
||||
|
||||
## 5. Sicherheitshinweise
|
||||
|
||||
@@ -483,8 +511,10 @@ erst nach `publish` und steht in keinem `needs`). Rot oder gelb heisst deshalb n
|
||||
etwas nicht ausgeliefert wurde. Zur Ursache im Job-Protokoll die Zeilen
|
||||
`SECURITY-SUMMARY <werkzeug> skipped reason=...` lesen: `download` oder `checksum` (Werkzeug
|
||||
nicht ladbar bzw. Summe stimmt nicht -- Netz pruefen, nie die Summe ohne Pruefung
|
||||
austauschen), `kein-pipx` / `install` (Semgrep), `kein-pnpm`, `abbild-fehlt` (das Abbild
|
||||
liegt nicht im Docker-Daemon des Hosts), `fehler` (Werkzeug ist abgestuerzt oder hat
|
||||
nichts geschrieben, z. B. Zeitlimit), `kein-bericht`. Ein haengender Lauf endet nach 30
|
||||
austauschen), `kein-docker` / `install` (Semgrep: Docker fehlt bzw. das Abbild liess sich nicht
|
||||
laden), `kein-pnpm`, `abbild-fehlt` (das Abbild
|
||||
liegt nicht im Docker-Daemon des Hosts), `zeitgrenze` (das Werkzeug hat sein eigenes Limit
|
||||
gerissen), `gesamtbudget` (die 25 Minuten waren aufgebraucht), `fehler` (Werkzeug ist
|
||||
abgestuerzt oder hat nichts geschrieben), `kein-bericht`. Ein haengender Lauf endet nach 30
|
||||
Minuten von selbst. Fehlt nur das Artefakt, ist das erwartbar (best effort); die Zahlen
|
||||
stehen trotzdem im Protokoll.
|
||||
|
||||
Reference in New Issue
Block a user