From 8a1218af6a877bb3b8e4f1104ce162511837c084 Mon Sep 17 00:00:00 2001 From: Schalli Date: Fri, 9 Oct 2026 20:59:12 +0200 Subject: [PATCH] docs(quick-261009-p0m): Review-Befunde im Sicherheitsprotokoll und in den Anleitungen nachgetragen Co-Authored-By: Claude Opus 5.5 (1M context) --- docs/anleitung-betrieb.md | 6 ++++ docs/anleitung-entwicklung.md | 23 ++++++++++++--- docs/ci-cd-setup.md | 54 +++++++++++++++++++++++++++-------- docs/sicherheitsprotokoll.md | 16 +++++++---- 4 files changed, 78 insertions(+), 21 deletions(-) diff --git a/docs/anleitung-betrieb.md b/docs/anleitung-betrieb.md index e41b7f3..7196ef8 100644 --- a/docs/anleitung-betrieb.md +++ b/docs/anleitung-betrieb.md @@ -555,6 +555,12 @@ was dabei passiert: [Sicherheitsprotokoll](sicherheitsprotokoll.md) ein (Eintrag unter „Verlauf“, neue Befunde in „Einordnung der Befunde“). Ein neuer Befund der Stufe „Hoch“ wird vor der Freigabe behoben oder im Protokoll begründet. + Hat sich seit der letzten Freigabe etwas an den Abbildern geändert (Dockerfile, + Abhängigkeiten), startet Claude außerdem das fertige Server-Abbild einmal gegen eine + frische, leere Datenbank: `bash .gitea/scripts/image-start-check.sh `. Die + Probe legt dafür eine kurzlebige Testdatenbank an, wendet alle Migrationen an, wartet auf die + Startzeile der API und räumt danach alles weg; sie berührt weder alpha noch live. Endet sie + nicht mit „frische-datenbank ok“, wird nicht freigegeben. 3. **Zusammenführen und taggen:** Erst dann wird zusammengeführt und getaggt: ```bash diff --git a/docs/anleitung-entwicklung.md b/docs/anleitung-entwicklung.md index 59f9446..59aed80 100644 --- a/docs/anleitung-entwicklung.md +++ b/docs/anleitung-entwicklung.md @@ -868,11 +868,16 @@ keinem anderen Job abgewartet: Er kann weder Bau noch Tests noch die Veröffentl - Die Quellprüfungen (Abhängigkeiten, Semgrep, Trivy) lesen einen Export des eingecheckten Stands (`git archive HEAD`), gitleaks liest die Git-Geschichte. Nicht eingecheckte Dateien eines Arbeitsordners erreichen nie ein Werkzeug. -- Die Werkzeuge sind auf feste Fassungen festgelegt (gitleaks, Trivy, osv-scanner, Semgrep, pnpm). Die geladenen - Programme werden vor jeder Benutzung gegen eine SHA256-Prüfsumme im Skript geprüft; bei einer abweichenden Summe oder +- Die Werkzeuge sind auf feste Fassungen festgelegt (gitleaks, Trivy, osv-scanner, Semgrep, pnpm). Semgrep läuft als + Container aus dem offiziellen Abbild, angepinnt über seinen Digest (Docker prüft beim Laden, dass der Inhalt dazu passt); + eine Installation über PyPI gibt es nicht mehr. Die übrigen geladenen Programme werden vor jeder Benutzung gegen eine SHA256-Prüfsumme im Skript geprüft; bei einer abweichenden Summe oder fehlendem Netz wird nur dieses Werkzeug übersprungen. **Eine Fassung anheben:** im Kopf des Skripts Version, Adresse und Prüfsumme zusammen austauschen (die Summe stammt aus der offiziellen Prüfsummendatei der Veröffentlichung) und einmal lokal `sh .gitea/scripts/security-scan.sh all` laufen lassen. +- Das Skript hält ein Zeitbudget von 25 Minuten ein (der Job hat 30): Jedes Werkzeug hat ein eigenes Zeitlimit, und jede + Ergebniszeile wird ausgegeben, sobald das Werkzeug fertig ist – ein Abbruch des Jobs verschluckt also nichts. Wird ein + Limit gerissen, steht `skipped reason=zeitgrenze`, ist das Gesamtbudget aufgebraucht `gesamtbudget`. Prüft das Skript in + einem flachen Klon, meldet gitleaks `unvollstaendig (flacher Klon ...)` statt eines scheinbar sauberen Ergebnisses. - Das Ergebnis erscheint im Protokoll des Laufs als Zeilen `SECURITY-SUMMARY ...` (nur Zahlen) und, soweit der Runner es zulässt, als Download `sicherheitsberichte`. Einzelheiten und Fehlersuche stehen im [CI/CD-Runbook](ci-cd-setup.md). @@ -965,7 +970,11 @@ Beweis, dass dabei kein POST entsteht, wurde vor dem ersten Lauf gegen einen lok einmal doch nach einer Anmeldung (die Vorabprüfung meldet dann Status 401), legen Sie eine Datei **außerhalb des Repositorys** mit einer Zeile `benutzer:passwort` an und rufen das Skript mit `ZAP_BASIC_AUTH_FILE=Pfad` auf. Der Kopf gelangt über eine temporäre Datei mit Modus 0600 (wird beim Beenden entfernt) in den Container und nie auf eine Befehlszeile -oder in eine Ausgabe. Achtung: Der Bericht enthält dann die gesendeten Kopfzeilen und damit die Zugangsdaten; geben Sie ihn +oder in eine Ausgabe; Sonderzeichen wie `"` oder `\` im Passwort sind erlaubt, weil die Zugangsdaten nur als base64-Text +weitergereicht werden. Der Haken schickt den Kopf **nur an das Ziel** (`ZAP_TARGET`), nie an andere Adressen (Weiterleitungen, +fremde Seiten, Dienste von ZAP selbst). Der Berichtsordner hat Modus 700 (nur der ZAP-Benutzer mit Kennung 1000 schreibt, kein +anderer Benutzer des Rechners liest); hat Ihr Konto nicht die Kennung 1000, übergibt das Skript den Ordner für die Dauer des +Laufs an diese Kennung und danach wieder an Sie zurück. Achtung: Der Bericht enthält dann die gesendeten Kopfzeilen und damit die Zugangsdaten; geben Sie ihn nicht weiter. Der Ordner `security-reports/` ist von Git ausgeschlossen. ## Konventionen und Fallstricke @@ -984,7 +993,13 @@ ein Paket, das nur unter `devDependencies` steht, scheitert das erst im Containe laufen mit allen Abhängigkeiten und fangen es nicht. Dann gehört das Paket in `dependencies`. **Beweis nach jeder Änderung an den Abbildern:** ein Start gegen eine frische, leere Datenbank (alle Migrationen laufen, die Zeile „Tessera API running“ erscheint) plus die Rauchtests am neu gebauten -Stack – so wie es `checks/fresh-db-start.sh` im Auftrag quick-261009-p0m vormacht. +Stack. Die Startprobe liegt versioniert im Repository: `bash .gitea/scripts/image-start-check.sh [Abbild]` +(ohne Angabe: `tessera-ctl-api:latest`). Sie startet eine kurzlebige Testdatenbank und das Abbild in einem eigenen Docker-Netz, +wartet auf „Tessera API running“, prüft, dass die Migrationen angewendet wurden, und räumt alles auf; Erfolg heißt Ausgabe +„frische-datenbank ok“ und Exit 0. Die Pipeline ruft sie nicht auf, sie gehört in die Freigabe-Checkliste (Betriebsanleitung, +Kapitel 9). **Der Bau scheitert ausdrücklich**, wenn der Prisma-Client nicht erzeugt werden konnte (eigener Schritt +`prisma generate` mit Prüfung in der Stufe `prod-deps`, denn der `postinstall` verschluckt Fehler) oder wenn npm, npx, corepack +oder yarn im Laufzeitabbild geblieben sind (Platzhalter statt fester Versionspfade, danach eine Prüfung). **Schutz-Kopfzeilen der Weboberfläche (quick-261009-p0m):** `apps/web/next.config.ts` sendet für alle Pfade `X-Content-Type-Options`, `Referrer-Policy`, `X-Frame-Options: SAMEORIGIN`, eine diff --git a/docs/ci-cd-setup.md b/docs/ci-cd-setup.md index 3cfcbf8..8525106 100644 --- a/docs/ci-cd-setup.md +++ b/docs/ci-cd-setup.md @@ -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:` 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 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. diff --git a/docs/sicherheitsprotokoll.md b/docs/sicherheitsprotokoll.md index 1e46963..e3ca07a 100644 --- a/docs/sicherheitsprotokoll.md +++ b/docs/sicherheitsprotokoll.md @@ -15,7 +15,7 @@ Das Protokoll enthält bewusst keine Passwörter, keine Zugangsdaten und keine A - **Eigener Quelltext:** Ein einziger echter Härtungspunkt wurde gefunden (die Längenprüfung bei der Entschlüsselung gespeicherter Geheimnisse, Schweregrad niedrig); er ist am 9. Oktober 2026 behoben und durch Tests abgesichert. Alles andere sind Fehlalarme oder bewusste, dokumentierte Entscheidungen. - **Automatische Prüfung:** Seit dem 9. Oktober 2026 läuft nach jedem Bau der Plattform automatisch eine Sicherheitsprüfung. Sie meldet nur und hält den Bau nie an. Ihr Abschlusslauf am selben Tag, im echten Bau-Umfeld auf dem bereinigten Stand, fand keine Zugangsdaten in der gesamten Geschichte und keinen kritischen Fund in den Bausteinen im Betrieb; die Zahlen vorher und nachher stehen im Abschnitt „Stand nach der Behebung“. - **Prüfung von außen:** Vor jeder Freigabe wird der Testserver alpha wie ein Besucher ohne Konto angesehen, rein passiv und ohne Angriffe. Der erste Lauf am 9. Oktober 2026 (direkt gegen die Anwendung, ohne den vorgeschalteten Proxy) fand nichts Hohes, 2 mittlere und 6 niedrige Hinweise sowie 3 reine Informationen; alle betreffen fehlende Schutz-Kopfzeilen der Weboberfläche. Die Anwendung sendet diese Kopfzeilen seit dem 9. Oktober 2026 selbst (bis auf eine vollständige Inhaltsrichtlinie, die offen bleibt). Der Lauf über die öffentliche Adresse steht noch aus und zeigt, ob auch der Proxy sie durchreicht. -- **Bisherige Prüfungen:** Acht Code-Prüfungen größerer Änderungen mit zusammen 89 Befunden; 76 davon sind behoben, die übrigen 13 sind Hinweise der niedrigsten Stufe. Alle kritischen Befunde und alle Warnungen sind behoben. +- **Bisherige Prüfungen:** Neun Code-Prüfungen größerer Änderungen mit zusammen 98 Befunden; 84 davon sind behoben. Offen sind 14: 13 Hinweise der niedrigsten Stufe und eine Warnung zur Pipeline, die erst im ersten echten Lauf nach dem Hochladen bestätigt werden kann (siehe „Einordnung der Befunde“). Alle kritischen Befunde sind behoben. - **Was noch zu tun ist:** Die Abbilder enthalten seit dem 9. Oktober 2026 keine Entwicklungswerkzeuge und keine Paketverwaltung mehr (das Server-Abbild ist von 1,66 GB bei der ersten Prüfung auf 1,12 GB geschrumpft, seine Fundzahl von 6 kritischen und 116 hohen auf 0 kritische und 6 hohe gefallen; das Web-Abbild von 2 kritischen und 19 hohen auf 0 kritische und 3 hohe). Offen bleiben einzelne Bausteine ohne bereinigte Fassung, die Bausteine, die erst mit einer neuen Hauptversion zu beheben sind, einige Hinweise zu Bausteinen der Desktop-App, die Gesundheitsprüfung der Weboberfläche, die vollständige Inhaltsrichtlinie sowie die Außenprüfung über die öffentliche Adresse; sie werden bei neuen Fassungen der Hersteller und bei der nächsten Außenprüfung erneut angesehen. Der Stand jedes einzelnen Punkts steht in der Tabelle „Einordnung der Befunde“, eine Liste in Alltagssprache im Abschnitt „Stand nach der Behebung“. ## So lesen Sie dieses Protokoll @@ -49,7 +49,7 @@ Immer wenn eine neue Fassung von Tessera gebaut wird, läuft zum Schluss ein eig - **Er sieht keine Geheimnisse.** Der Schritt bekommt keinerlei Passwörter oder Zugangsschlüssel der Pipeline. - **Er prüft genau den eingecheckten Stand.** Nicht eingecheckte Dateien eines Arbeitsrechners erreichen keines der Werkzeuge und keinen Bericht. -Die Zahlen erscheinen als Zeilen, die mit „SECURITY-SUMMARY“ beginnen, im Protokoll des Laufs. Die Rohberichte hängen, soweit der Server das zulässt, als Download namens „sicherheitsberichte“ am Lauf. Die Werkzeuge sind auf feste Fassungen festgelegt und werden vor jeder Verwendung gegen eine Prüfsumme geprüft; passt die Prüfsumme nicht oder ist das Netz nicht erreichbar, wird nur das betroffene Werkzeug übersprungen. Die technischen Einzelheiten stehen im [Pipeline-Handbuch](ci-cd-setup.md) und in der [Entwicklungsanleitung](anleitung-entwicklung.md#sicherheitsprüfungen). +Die Zahlen erscheinen als Zeilen, die mit „SECURITY-SUMMARY“ beginnen, im Protokoll des Laufs. Die Rohberichte hängen, soweit der Server das zulässt, als Download namens „sicherheitsberichte“ am Lauf. Die Werkzeuge sind auf feste Fassungen festgelegt und werden vor jeder Verwendung gegen eine Prüfsumme geprüft; passt die Prüfsumme nicht oder ist das Netz nicht erreichbar, wird nur das betroffene Werkzeug übersprungen. Jedes Werkzeug hat ein eigenes Zeitlimit; zusammen halten sie sich an 25 Minuten, das Zeitlimit des ganzen Schritts beträgt 30. Jedes Werkzeug meldet seine Zeile, sobald es fertig ist, damit ein Abbruch keine fertigen Ergebnisse verschluckt. Wird die Prüfung in einer verkürzten Kopie der Geschichte ausgeführt, meldet sie bei den Zugangsdaten „unvollständig“ statt eines scheinbar sauberen Ergebnisses. Die technischen Einzelheiten stehen im [Pipeline-Handbuch](ci-cd-setup.md) und in der [Entwicklungsanleitung](anleitung-entwicklung.md#sicherheitsprüfungen). ### Zugangsdaten im Quelltext und in seiner Geschichte (gitleaks) @@ -65,7 +65,7 @@ Tessera besteht zu einem großen Teil aus Bausteinen anderer Hersteller. Drei We ### Eigener Quelltext (Semgrep) -Semgrep liest den von uns geschriebenen Quelltext und sucht nach Mustern, die erfahrungsgemäß zu Fehlern führen, etwa unsichere Verschlüsselungsaufrufe oder ausgeschaltete Zertifikatsprüfungen. Das Werkzeug meldet viel mehr als echte Fehler; jeder Treffer wird deshalb von Hand beurteilt. Testdateien, Testdaten und Planungsnotizen sind ausgenommen, denn sie werden nicht ausgeliefert. +Semgrep liest den von uns geschriebenen Quelltext und sucht nach Mustern, die erfahrungsgemäß zu Fehlern führen, etwa unsichere Verschlüsselungsaufrufe oder ausgeschaltete Zertifikatsprüfungen. Das Werkzeug meldet viel mehr als echte Fehler; jeder Treffer wird deshalb von Hand beurteilt. Testdateien, Testdaten und Planungsnotizen sind ausgenommen, denn sie werden nicht ausgeliefert. Semgrep läuft in seinem offiziellen Container, der über eine feste Kennung (den Digest) angepinnt ist: Docker prüft beim Laden, dass der Inhalt genau zu dieser Kennung passt, und es werden keine Zusatzpakete frei aus dem Internet nachgeladen. ### Fertige Abbilder (Trivy) @@ -89,7 +89,7 @@ Neben den Werkzeugen gibt es Prüfungen, die durch Lesen und Nachdenken entstehe ### Code-Prüfungen -Acht Code-Prüfungen wurden bisher durchgeführt. Die Spalte „Nachweis“ nennt die interne Bezeichnung der Prüfung. +Neun Code-Prüfungen wurden bisher durchgeführt. Die Spalte „Nachweis“ nennt die interne Bezeichnung der Prüfung. | Datum | Prüfung | Umfang | Ergebnis | Stand | Nachweis | |-------|---------|--------|----------|-------|----------| @@ -101,8 +101,9 @@ Acht Code-Prüfungen wurden bisher durchgeführt. Die Spalte „Nachweis“ nenn | 08.10.2026 | Modul Dateien (Nextcloud) | 54 Dateien | 2 kritisch, 9 Warnungen, 7 Hinweise (18). Kritisch: Die Begrenzung von Passwortversuchen ließ sich durch gleichzeitige Anfragen umgehen, und ein Benutzer mit der Freigabe „Verwalten“ konnte die Nextcloud-Adresse für alle Benutzer umlenken | Alle 18 behoben am 08.10.2026 | quick-261008-mzu | | 09.10.2026 | Modul Dateien, Teilen (Nextcloud-Freigaben) | 5 Änderungen | 1 kritisch, 4 Warnungen, 6 Hinweise (11). Kritisch: Pfade und Kennungen wurden beim Anzeigen verändert, wodurch Freigaben auf die falsche Datei zeigen konnten | Alle 11 behoben am 09.10.2026; dazu zwei Nachbesserungen aus der Prüfung (Anzeige der Rechte eines Ordners, Zähler gegen zu viele Freigabe-Versuche) | quick-261009-dkv | | 09.10.2026 | Zertifikatsmanager (Umbau, Abruf fremder Adressen, ZIP) | 62 Dateien | 3 kritisch, 7 Warnungen, 5 Hinweise (15). Kritisch: (1) eine „ZIP-Bombe“, bei der eine gefälschte Größenangabe alle Grenzen umging; (2) ein Suchmuster für Zertifikatsblöcke, das bei einer kleinen Datei die Programmschleife minutenlang blockierte; (3) PFX-Dateien mit Umlauten im Passwort ließen sich nicht richtig lesen und schreiben | Alle 15 behoben am 09.10.2026. Jeder kritische Befund hat einen Test, der gegen den alten Code rot war. Der Schutz vor Abrufen interner Adressen wurde dabei zusätzlich gehärtet (siehe unten) | quick-261009-ikt | +| 09.10.2026 | Sicherheitsauftrag (Prüfskripte der Pipeline, Außenprüfung, Abbilder, Kopfzeilen, Entschlüsselung) | 24 Dateien | 0 kritisch, 5 Warnungen, 4 Hinweise (9). Die Warnungen betrafen: den Prisma-Baustein des Server-Abbilds, der bei einem Fehler still fehlen konnte; Semgrep, das ohne feste Prüfsumme aus dem Internet geladen wurde; die Zeitgrenzen der Prüfung, die zusammen weit über dem Zeitlimit des Jobs lagen; die Anmeldekopfzeile der Außenprüfung, die nicht auf das Ziel beschränkt war; und das Verhalten des Prüfschritts im ersten echten Pipeline-Lauf | 8 behoben am 09.10.2026 (4 Warnungen und 4 Hinweise), jeweils mit Gegenprobe. 1 Warnung offen: Ob der Prüfschritt auf dem echten Server grün bleibt und den einzigen Runner nicht aufhält, zeigt erst der erste echte Lauf | quick-261009-p0m | -**Summe:** 8 Prüfungen, 89 Befunde (13 kritisch, 43 Warnungen, 33 Hinweise). Behoben sind 76, darunter alle kritischen Befunde und alle Warnungen und 20 von 33 Hinweisen. Offen oder nicht bearbeitet sind 13 Hinweise der niedrigsten Stufe. +**Summe:** 9 Prüfungen, 98 Befunde (13 kritisch, 48 Warnungen, 37 Hinweise). Behoben sind 84, darunter alle kritischen Befunde, 47 von 48 Warnungen und 24 von 37 Hinweisen. Offen oder nicht bearbeitet sind 14: 13 Hinweise der niedrigsten Stufe und die eine Warnung zum ersten echten Pipeline-Lauf. Drei Begriffe aus der Tabelle in Alltagssprache: Eine **ZIP-Bombe** ist eine kleine Datei, die sich beim Entpacken auf ein Vielfaches ihrer Größe aufbläht und den Server überlasten soll. Ein **Suchmuster** (regulärer Ausdruck) kann bei bestimmten Eingaben extrem lange rechnen; so lässt sich mit einer winzigen Datei ein Server lahmlegen. **PFX** ist ein passwortgeschütztes Dateiformat, das Zertifikat und Schlüssel zusammenfasst. @@ -233,6 +234,7 @@ Die Tabelle beurteilt jeden Befund der ersten vollständigen Prüfung. Sie wird | Testschlüssel und Testwerte in Testdaten, Testdateien und Planungsnotizen | Zertifikatsmanager (Testdaten), drei Testdateien, eine Planungsnotiz, eine Testkomponente | Fehlalarm | bewusst akzeptiert | Die Schlüssel sind eigens zum Prüfen der Software erzeugt und schützen nichts. Der Ordner mit den Testdaten und die einzelnen Dateien stehen in den Ausnahmelisten (gitleaks, Trivy, Semgrep) | | Beschriftung „Benutzer/Passwort“, Tabellenzeile einer Prüfliste und Beispielaufruf an einen lokalen Wegwerf-Testserver | Sprachdatei, Planungsnotizen | Fehlalarm | bewusst akzeptiert | Keines der drei enthält ein echtes Geheimnis: ein Beschriftungstext, eine Beispielzeile und der Testzugang eines wegwerfbaren lokalen Testservers. Alle drei sind einzeln in den Ausnahmelisten eingetragen | | Hinweise zu Umleitung nach der Anmeldung, zusammengesetzten Suchmustern und Durchlaufen von Objekten | Weboberfläche, Server | Fehlalarm | bewusst akzeptiert | Die Umleitung nach der Anmeldung läuft durch eine Prüffunktion, die nur Pfade der eigenen Seite zulässt. Die Suchmuster werden aus festen Konstanten gebaut, nicht aus Benutzereingaben. Das Durchlaufen der Objekte liest nur | +| Verhalten des Prüfschritts im ersten echten Pipeline-Lauf (Code-Prüfung des Sicherheitsauftrags, 9. Oktober 2026) | Pipeline | Niedrig | offen | Der Schritt ist so gebaut, dass er nie rot färbt und den Bau nicht aufhält, und wurde im selben Container-Abbild wie die Pipeline nachgestellt. Ob der echte Server die Einstellungen „Fehler ignorieren“ und „Zeitlimit“ für einen einzelnen Schritt so beachtet, und ob der einzige Runner nach einem Bau bis zu 25 Minuten belegt ist, lässt sich nur im ersten echten Lauf sehen (gemessen auf dem Entwicklungsrechner: etwa eine Minute bei warmem Zwischenspeicher). Wird der Runner zum Engpass, wandert die Prüfung in einen nächtlichen Lauf | | Pipeline-Datei: Bausteine der Pipeline mit beweglichen Versionsnamen (14 Stellen seit dem neuen Prüfschritt) und ein Installationsaufruf per Herunterladen-und-Ausführen | Pipeline | Niedrig | offen | Die Pipeline läuft auf eigenen Servern ohne fremde Zugriffe. Bewegliche Versionsnamen könnten sich aber unbemerkt ändern; sie sollen fest eingetragen werden | | Einstellungen zum Absichern der Paketverwaltung (drei Werte) | Arbeitsbereich-Datei | Niedrig | offen | Diese Einstellungen stärken die Lieferkette. Ob sie in der eingesetzten Fassung 9.15 des Paketverwalters wirken, ist noch nicht geprüft | | Fehlende Gesundheitsprüfung im Bauplan des Server-Abbilds | Abbild `api` | Niedrig | bewusst akzeptiert | Die Gesundheitsprüfung liegt in der Compose-Datei, die den Server startet und seine Erreichbarkeit überwacht | @@ -270,6 +272,10 @@ Die Beurteilung jeder Meldung steht in der Tabelle „Einordnung der Befunde“. Der neueste Eintrag steht oben. +### 2026-10-09 — Codeprüfung des Sicherheitsauftrags + +Die Änderungen des Sicherheitsauftrags selbst (Prüfskripte der Pipeline, Außenprüfung, Abbilder, Kopfzeilen, Entschlüsselung, Bausteine) wurden von einer zweiten Stelle durchgesehen. Ergebnis: keine kritischen Befunde, 5 Warnungen und 4 Hinweise; nichts davon hielt eine Veröffentlichung auf. Behoben wurden am selben Tag: **(1)** Das Server-Abbild erzeugt den Prisma-Baustein jetzt in einem eigenen Schritt, dessen Fehler den Bau abbricht; vorher konnte der Baustein still fehlen und das Abbild erst beim Start sterben. Eine absichtlich kaputte Beschreibung bewies, dass der Bau jetzt scheitert. Die Startprobe gegen eine frische Datenbank liegt nun versioniert im Projekt und steht in der Freigabe-Checkliste. **(2)** Semgrep kommt aus dem offiziellen Container mit fester Kennung statt aus dem Paketindex mit frei aufgelösten Zusatzpaketen. **(3)** Die Zeitgrenzen der Werkzeuge ergeben zusammen höchstens 25 Minuten (vorher rund 140), ein Gesamtbudget kürzt sie, und jedes Werkzeug meldet sein Ergebnis sofort. **(4)** Die Anmeldekopfzeile der Außenprüfung geht nur noch an das Ziel; die Gegenprobe über einen Zwischenserver zeigte: Ziel bekam sie, ein zweiter Rechner und derselbe Rechner an einem anderen Anschluss nicht. **(5)** Hinweise: Die Programme zur Paketverwaltung werden mit Platzhaltern entfernt und der Bau scheitert, falls eines bleibt; der Berichtsordner der Außenprüfung ist nur noch für den ZAP-Benutzer zugänglich statt für alle; Passwörter mit Anführungszeichen oder Rückstrich werden sicher behandelt; ein flacher Klon wird bei den Zugangsdaten als „unvollständig“ gemeldet; und ein Kommentar zur Doppelung der Kopfzeilen mit dem Proxy wurde richtiggestellt. **Offen:** das Verhalten des Prüfschritts im ersten echten Pipeline-Lauf (siehe „Einordnung der Befunde“). + ### 2026-10-09 — Stand nach der Behebung Abschlusslauf der automatischen Prüfung auf dem bereinigten Stand, im Container-Abbild der Pipeline, mit frisch gebauten Abbildern: Keine Zugangsdaten in der gesamten Geschichte, keine kritische Meldung mehr bei den Bausteinen im Betrieb (151 auf 12 Meldungen), das Server-Abbild von 6 kritischen und 116 hohen Funden auf 0 und 6, das Web-Abbild von 2 und 19 auf 0 und 3. Die Längenprüfung des Echtheits-Codes wird von Semgrep nicht mehr gemeldet. Die Zahlen vorher und nachher stehen im Abschnitt „Stand nach der Behebung“, die Beurteilung jedes Befunds in „Einordnung der Befunde“ (jede Zeile hat Stand und Begründung). **Offen:** xlsx, node-forge, nodemailer, sharp, deepmerge-ts, einige Hinweise zu Bausteinen der Desktop-App, die Gesundheitsprüfung der Weboberfläche, die vollständige Inhaltsrichtlinie und der Lauf über die öffentliche Adresse.