KI-Sicherheitsanalyse-security-audit-skill: Difference between revisions
No edit summary |
|||
| (67 intermediate revisions by the same user not shown) | |||
| Line 4: | Line 4: | ||
Große Sprachmodelle können Code lesen, Zusammenhänge über viele Dateien hinweg verfolgen und Werkzeuge bedienen. Damit liegt es nahe, sie für die Suche nach Sicherheitslücken einzusetzen. Offen ist, wie belastbar ihre Ergebnisse sind, denn ein falscher Befund ist in der Sicherheitsanalyse teuer. |
Große Sprachmodelle können Code lesen, Zusammenhänge über viele Dateien hinweg verfolgen und Werkzeuge bedienen. Damit liegt es nahe, sie für die Suche nach Sicherheitslücken einzusetzen. Offen ist, wie belastbar ihre Ergebnisse sind, denn ein falscher Befund ist in der Sicherheitsanalyse teuer. |
||
Der Bericht folgt den vier Fragen |
Der Bericht folgt den vier Fragen: |
||
# Wie funktioniert eine KI-Agent-basierte Sicherheitsanalyse? |
|||
# Welche Werkzeuge sind verfügbar und geeignet? |
# Welche Werkzeuge sind verfügbar und geeignet? |
||
# Wie funktioniert eine KI-Agent-basierte Sicherheitsanalyse? |
|||
# Wo liegen Stärken, Schwächen und Kosten? |
|||
# Können die gefundenen Schwachstellen verstanden und verifiziert werden? |
# Können die gefundenen Schwachstellen verstanden und verifiziert werden? |
||
# Wo liegen Stärken, Schwächen und Kosten? |
|||
== Werkzeugfamilien == |
== Werkzeugfamilien == |
||
| Line 19: | Line 18: | ||
== Der Cloudflare security-audit skill == |
== Der Cloudflare security-audit skill == |
||
=== |
=== Steckbrief === |
||
{| class="wikitable" |
|||
Cloudflare ist ein großer Anbieter für den Schutz von Websites. Der Skill ist auf GitHub unter MIT-Lizenz veröffentlicht. Laut dem Cloudflare-Blogartikel „Build your own vulnerability harness“ war er der Ausgangspunkt für Cloudflares internes System zur Schwachstellensuche, das später zu einer großen Pipeline über mehr als 128 Repositories ausgebaut wurde. |
|||
! Merkmal !! Beschreibung |
|||
|- |
|||
| Herkunft || Cloudflare, großer Anbieter für den Schutz von Websites, auf GitHub unter MIT-Lizenz veröffentlicht |
|||
|- |
|||
| Bedeutung || Laut Blogartikel „Build your own vulnerability harness“ Ausgangspunkt für Cloudflares interne Schwachstellensuche, später ausgebaut zu einer Pipeline über mehr als 128 Repositories |
|||
|- |
|||
| Form || Der Skill ist '''kein Scanner und kein Programm'''. Er ist ein Ordner <code>skills/security-audit/</code> mit rund 5.300 Zeilen Anweisungen und zwei Prüfskripten |
|||
|- |
|||
| Modi || '''Anleitungsmodus''' (Standard): beantwortet Sicherheitsfragen ohne Berichtsdateien.<br>'''Vollständiger Audit-Modus''': Dieser wird nur auf ausdrückliche Anfrage („Security Audit“, „Pen-Test“, „Full Security Review“) durchgeführt und durchläuft alle sechs Phasen. Im Projekt wird nur dieser Modus verwendet.'' |
|||
|} |
|||
=== Bestandteile === |
=== Bestandteile === |
||
Der Skill ist '''kein Scanner und kein Programm'''. Er ist ein Ordner <code>skills/security-audit/</code> mit rund 5.300 Zeilen Anweisungen und zwei Prüfskripten: |
|||
{| class="wikitable" |
{| class="wikitable" |
||
| Line 30: | Line 38: | ||
| <code>SKILL.md</code> || Einstieg: Betriebsarten, Sicherheitsregeln, Profile, Budget, Schweregradskala, verbotene Fehler |
| <code>SKILL.md</code> || Einstieg: Betriebsarten, Sicherheitsregeln, Profile, Budget, Schweregradskala, verbotene Fehler |
||
|- |
|- |
||
| <code>RECONNAISSANCE.md</code> || Phase 1: Aufklärung des Projekts und Aufbau |
| <code>RECONNAISSANCE.md</code> || Phase 1: Die Aufklärung des Projekts und der Aufbau von "architecture.md" und "Coverage Ledgers" |
||
|- |
|- |
||
| <code>HUNTING.md</code>, <code>ATTACK-CLASSES.md</code> || Phase 2: Aufbau der Suchaufträge und Angriffsklassen (Injection, Zugriffskontrolle, Dateien, Kryptografie, Geschäftslogik …) |
| <code>HUNTING.md</code>, <code>ATTACK-CLASSES.md</code> || Phase 2: Aufbau der Suchaufträge und Angriffsklassen (Injection, Zugriffskontrolle, Dateien, Kryptografie, Geschäftslogik …) |
||
| Line 44: | Line 52: | ||
'''Warum die Prüfskripte wichtig sind:''' Ein Sprachmodell kann eine JSON-Datei schreiben, die richtig aussieht, aber unvollständig oder widersprüchlich ist. Die Skripte arbeiten ohne KI und lehnen etwa fehlende Felder, ungültige Pfade oder einen Schweregrad für einen unbestätigten Fund ab. |
'''Warum die Prüfskripte wichtig sind:''' Ein Sprachmodell kann eine JSON-Datei schreiben, die richtig aussieht, aber unvollständig oder widersprüchlich ist. Die Skripte arbeiten ohne KI und lehnen etwa fehlende Felder, ungültige Pfade oder einen Schweregrad für einen unbestätigten Fund ab. |
||
=== Zwei Modi === |
|||
# '''Anleitungsmodus''' (''guidance mode''): Standard. Beantwortet Sicherheitsfragen, ohne Berichtsdateien zu schreiben. |
|||
# '''Vollständiger Audit-Modus''' (''full audit mode''): nur bei ausdrücklicher Anfrage („security audit“, „pen-test“, „full security review“). Durchläuft alle sechs Phasen und schreibt die Berichtsdateien. |
|||
Im Projekt wurde ausschließlich der vollständige Audit-Modus verwendet. |
|||
=== Vier Rollen === |
=== Vier Rollen === |
||
| Line 66: | Line 68: | ||
|} |
|} |
||
'''Prinzip: Wer findet, bewertet nicht.''' Ein Agent, der seinen eigenen Fund bewertet, neigt zur Selbstbestätigung. Jeder Subagent arbeitet in <code>agents/<agent-id>/scratch/</code> und liefert strukturiertes JSON an den Koordinator. |
|||
'''Warum diese Trennung?''' Ein Agent, der einen Fehler findet und ihn anschließend selbst bewertet, neigt dazu, sich selbst zu bestätigen. Der Skill verbietet das: Wer findet, bewertet nicht. Das entspricht dem Vier-Augen-Prinzip beim menschlichen Code-Review. |
|||
Jeder Subagent arbeitet in einem eigenen Ordner unter <code>agents/<agent-id>/scratch/</code> und gibt sein Ergebnis als strukturiertes JSON zurück. Nur der Koordinator sammelt diese Ergebnisse und schreibt sie in die gemeinsamen Dateien. |
|||
=== Sechs Phasen === |
=== Sechs Phasen === |
||
[[File:Ablauf 6 Phasen.png|thumb|center|800px|Ablauf des Security-audit Skill]] |
|||
{| class="wikitable" |
|||
'''Phase 1: Aufklärung''' (''reconnaissance''). Der Koordinator startet vier Agenten gleichzeitig, die nur lesen: |
|||
! Phase !! Was passiert !! Ergebnis |
|||
|- |
|||
| '''1 Aufklärung'''<br>''reconnaissance'' || Der Koordinator startet vier Agenten gleichzeitig, die nur lesen: |
|||
* Agent 1a: Produkt, Benutzer, Sprachen und Frameworks, Build- und Testbefehle. |
* Agent 1a: Produkt, Benutzer, Sprachen und Frameworks, Build- und Testbefehle. |
||
* Agent 1b: Rollen, Berechtigungen, Anmelde- und Rechteprüfungen. |
* Agent 1b: Rollen, Berechtigungen, Anmelde- und Rechteprüfungen. |
||
* Agent 1c: Eingabepunkte (HTTP-Anfragen, Datei-Uploads usw.) und wohin die Daten im Code fließen. |
* Agent 1c: Eingabepunkte (HTTP-Anfragen, Datei-Uploads usw.) und wohin die Daten im Code fließen. |
||
* Agent 1d: Was lässt sich lokal sicher testen, und bietet der Rechner die geforderte Sandbox? |
* Agent 1d: Was lässt sich lokal sicher testen, und bietet der Rechner die geforderte Sandbox? |
||
|| <code>architecture.md</code>, <code>coverage-ledger.json</code> |
|||
|- |
|||
| '''2 Suche'''<br>''hunting'' || Hunter erhalten Prüfeinheiten samt Angriffsklassen-Anweisungen im Wortlaut und verfolgen eine Eingabe bis zur kritischen Stelle (''sink'', z. B. Datenbankabfrage). Ein Kritiker sucht danach Lücken, diese werden neue Einheiten, falls das Budget eine weitere Welle erlaubt. || Kandidaten als JSON |
|||
|- |
|||
| '''3 Validierung'''<br>''validation'' || '''Kern des Skills:''' Ein neuer Prüfer liest jede zitierte Zeile erneut, sucht übersehene Schutzmechanismen und versucht zu widerlegen. || eines von drei Urteilen |
|||
|- |
|||
| '''4 Strukturierte Ausgabe''' || Urteile werden geschrieben, Prüfskripte kontrollieren das Format. || <code>findings.json</code> |
|||
|- |
|||
| '''5 Zweite Verifikation''' || Weitere neue Agenten prüfen die Aussagen erneut, wesentliche Änderungen prüft ein zusätzlicher Agent. || bestätigte Datensätze |
|||
|- |
|||
| '''6 Bericht''' || Bericht nur aus geprüften Datensätzen; er darf kein Urteil ändern. || <code>REPORT.md</code>, <code>FINDINGS-DETAIL.md</code>, <code>NEEDS-VALIDATION.md</code> |
|||
|} |
|||
'''Endbedingung:''' Ein Lauf endet nie mitten in einer Phase. Entweder sind alle Berichtsdateien geschrieben und beide Skripte bestanden, oder der Lauf wird mit Grund als „incomplete“ markiert. |
|||
Daraus entstehen <code>architecture.md</code> und <code>coverage-ledger.json</code>. |
|||
'''Phase 2: Suche''' (''hunting''). Der Koordinator zerlegt die Arbeit in Prüfeinheiten und gibt jedem Hunter eine oder mehrere Einheiten samt der passenden Angriffsklassen-Anweisungen im Wortlaut. Der Hunter verfolgt eine Eingabe vom Eingabepunkt über alle Prüfungen bis zur kritischen Stelle (''sink''), etwa einer Datenbankabfrage oder einem Befehlsaufruf, und liefert sein Ergebnis als JSON. Danach sucht ein Kritiker nach ungeprüften Bereichen; gefundene Lücken werden als neue Einheiten aufgenommen, sofern das Budget eine weitere Welle erlaubt. |
|||
'''Phase 3: Validierung''' (''validation''). Der Kern des Skills: Jeder Kandidat geht an einen '''neuen Prüfer''', der die Suche nicht gesehen hat. Er liest jede zitierte Codezeile erneut, sucht nach übersehenen Schutzmechanismen und versucht, den Fund zu widerlegen. Dann entscheidet er sich für eines von drei Urteilen. |
|||
'''Phase 4: Strukturierte Ausgabe''' (''structured output''). Alle Urteile werden in <code>findings.json</code> geschrieben, und die Prüfskripte kontrollieren das Format. |
|||
'''Phase 5: Zweite Verifikation''' (''independent record verification''). Weitere neue Agenten prüfen die endgültigen Aussagen ein zweites Mal. Ändert einer von ihnen etwas Wesentliches, prüft ein zusätzlicher Agent die Änderung. |
|||
'''Phase 6: Bericht''' (''reporting''). Erst jetzt entstehen <code>REPORT.md</code>, <code>FINDINGS-DETAIL.md</code> und <code>NEEDS-VALIDATION.md</code>, ausschließlich aus geprüften Datensätzen. Der Bericht darf kein Urteil verändern. |
|||
'''Endbedingung:''' Ein Lauf darf nicht mitten in einer Phase enden. Entweder sind alle Berichtsdateien geschrieben und beide Skripte bestanden, oder der Lauf wird als „incomplete“ mit genauem Grund markiert. |
|||
=== |
=== Urteile und Schweregrad === |
||
{| class="wikitable" |
{| class="wikitable" |
||
! Urteil !! Bedeutung !! Schweregrad? |
! Urteil !! Bedeutung !! Schweregrad? |
||
|- |
|- |
||
| <code>confirmed</code> || vollständige |
| <code>confirmed</code> || vollständige Codespur vom Eingabepunkt zur kritischen Stelle '''und''' lokal beobachtetes Ergebnis || ja |
||
|- |
|- |
||
| <code>needs_validation</code> || codebasierter Verdacht, |
| <code>needs_validation</code> || codebasierter Verdacht, dem genau '''ein''' Fakt fehlt, mit Prüfplan || nein |
||
|- |
|- |
||
| <code>rejected</code> || von einem Prüfer widerlegt || nein |
| <code>rejected</code> || von einem Prüfer widerlegt || nein |
||
|} |
|} |
||
Einträge mit <code>needs_validation</code> heißen |
Einträge mit <code>needs_validation</code> heißen hier '''Verdachtsfälle''' (''leads''). Für „confirmed“ muss der Code '''ausgeführt''' werden; fehlerhaft aussehender Code genügt nicht. |
||
{| class="wikitable" |
|||
=== Schweregradskala === |
|||
! Schweregrad (nur bestätigte Funde) !! Beispiel |
|||
|- |
|||
* '''critical:''' Ein nicht angemeldeter Angreifer führt Code aus, erhält vollen Datenbankzugriff oder übernimmt beliebige Konten. |
|||
| critical || nicht angemeldeter Angreifer führt Code aus, erhält vollen Datenbankzugriff oder übernimmt beliebige Konten |
|||
* '''high:''' Eine Sicherheitskontrolle wird mit echten Folgen vollständig umgangen, z. B. Anmeldung umgangen oder fremde Daten gelesen. |
|||
|- |
|||
* '''medium:''' echte Grenzverletzung mit begrenzter Wirkung oder seltenen Voraussetzungen. |
|||
| high || Sicherheitskontrolle vollständig umgangen, z. B. Anmeldung umgangen, fremde Daten gelesen |
|||
* '''low:''' Preisgabe nicht geheimer interner Informationen. |
|||
|- |
|||
* '''informational:''' bestätigt, aber mit minimaler Wirkung. |
|||
| medium || echte Grenzverletzung mit begrenzter Wirkung oder seltenen Voraussetzungen |
|||
|- |
|||
| low || Preisgabe nicht geheimer interner Informationen |
|||
|- |
|||
| informational || bestätigt, aber minimale Wirkung |
|||
|} |
|||
=== Coverage Ledger === |
=== Coverage Ledger === |
||
Das Coverage Ledger zerlegt das Projekt in Prüfeinheiten. Jede Einheit ist eine Kombination aus vier Teilen: |
Das Coverage Ledger zerlegt das Projekt in Prüfeinheiten. Jede Einheit ist eine Kombination aus vier Teilen: Eingabepunkt × Vertrauensgrenze × Teilsystem × Angriffsklasse. Jede Prüfeinheit hat einen Status |
||
: Eingabepunkt × Vertrauensgrenze × Teilsystem × Angriffsklasse |
|||
Beispiel: „POST /login“ × „Passwortprüfung“ × „Server“ × „SQL-Injection“. |
|||
{| class="wikitable" |
{| class="wikitable" |
||
| Line 139: | Line 143: | ||
|} |
|} |
||
Die meisten Werkzeuge sagen, was sie gefunden haben, aber nicht, was sie '''nicht''' geprüft haben. Das Ledger macht Lücken in der Abdeckung sichtbar. Niemand kann „alles geprüft“ behaupten, solange Einheiten zurückgestellt sind. |
|||
=== Fingerabdruck === |
=== Fingerabdruck === |
||
| Line 156: | Line 160: | ||
Das '''Budget''' ist die Höchstzahl der Agentenaufrufe über alle Phasen. Vor der Suche reserviert der Skill Aufrufe für Kritiker und Prüfer, damit die Hunter nicht das ganze Budget verbrauchen und am Ende niemand mehr prüfen kann. |
Das '''Budget''' ist die Höchstzahl der Agentenaufrufe über alle Phasen. Vor der Suche reserviert der Skill Aufrufe für Kritiker und Prüfer, damit die Hunter nicht das ganze Budget verbrauchen und am Ende niemand mehr prüfen kann. |
||
=== Sicherheitsregel: ohne Sandbox keine Ausführung === |
|||
Der untersuchte Code kann gefährlich sein, denn er enthält ja Lücken. Deshalb erlaubt der Skill die Ausführung von Zielcode nur in einer '''vom Betriebssystem erzwungenen Sandbox''' mit allen folgenden Eigenschaften: |
|||
* keine Verbindung zum externen Netzwerk; |
|||
* leere Umgebung, ohne Variablen oder Passwörter des Rechners; |
|||
* Zielcode nur lesbar; |
|||
* Schreiben nur in einen eigenen Arbeitsordner; |
|||
* harte Grenzen für CPU, Speicher, Prozesse und Laufzeit. |
|||
'''Fehlt eine Eigenschaft, führt der Skill nichts aus''', vermerkt den Grund als Blocker (''blocker'') und belässt den Fund bei „needs_validation“. Weitere Regeln: keine Anfragen an produktive Systeme, keine Installation von Abhängigkeiten, keine echten Zugangsdaten, keine Änderungen am Zielcode. Der Skill beschreibt Korrekturen nur. |
|||
=== Mehrere Läufe bauen aufeinander auf === |
=== Mehrere Läufe bauen aufeinander auf === |
||
Kennt ein zweiter Lauf den Ort des ersten, liest er dessen Ledger und Ergebnisse. Er konzentriert sich dann auf zurückgestellte Einheiten und ungeprüfte Hinweise und prüft alte Ergebnisse erneut. Laut Cloudflare findet ein einzelner Lauf etwa die Hälfte dessen, was wiederholte Läufe zusammen finden. |
Kennt ein zweiter Lauf den Ort des ersten, liest er dessen Ledger und Ergebnisse. Er konzentriert sich dann auf zurückgestellte Einheiten und ungeprüfte Hinweise und prüft alte Ergebnisse erneut. Laut Cloudflare findet ein einzelner Lauf etwa die Hälfte dessen, was wiederholte Läufe zusammen finden. |
||
=== Sicherheitsregel: ohne Sandbox keine Ausführung === |
|||
== Das Zielprojekt OWASP Juice Shop == |
|||
Zielcode darf nur in einer '''vom Betriebssystem erzwungenen Sandbox''' laufen: kein externes Netzwerk, leere Umgebung ohne Variablen und Passwörter, Zielcode nur lesbar, Schreiben nur im eigenen Arbeitsordner, harte Grenzen für CPU, Speicher, Prozesse und Laufzeit. Fehlt eine Eigenschaft, führt der Skill nichts aus, vermerkt einen Blocker und belässt den Fund bei <code>needs_validation</code>. Zudem verboten: Anfragen an produktive Systeme, Installation von Abhängigkeiten, echte Zugangsdaten, Änderungen am Zielcode (Korrekturen werden nur beschrieben). |
|||
== Das Zielprojekt: OWASP Juice Shop == |
|||
{| class="wikitable" |
|||
'''OWASP Juice Shop''' ist ein fiktiver Webshop für Säfte, der '''absichtlich''' voller Sicherheitslücken ist und für Sicherheitstrainings verwendet wird: |
|||
! Merkmal !! Beschreibung |
|||
* '''Server:''' TypeScript, Node.js, Express; SQLite über Sequelize sowie die In-Memory-Datenbank MarsDB; |
|||
|- |
|||
* '''Oberfläche:''' Angular; |
|||
| Was || fiktiver Saft-Webshop, '''absichtlich''' voller Lücken, für Sicherheitstrainings |
|||
* '''Anmeldung:''' JWT-Tokens. |
|||
|- |
|||
| Technik || Server: TypeScript, Node.js, Express, SQLite (Sequelize), MarsDB (In-Memory)<br>Oberfläche: Angular · Anmeldung: JWT |
|||
|- |
|||
| Warum dieses Projekt || '''Lösungsschlüssel''' <code>data/static/challenges.yml</code> mit '''116 Challenges''' liefert eine Referenz (''ground truth''), um Treffer und Lücken des Werkzeugs zu messen. Juice Shop ist nicht klein, dieser Vorteil überwiegt aber. |
|||
|- |
|||
| safetyMode || schaltet ca. 19 gefährliche Challenges (Codeausführung, Dateizugriff) ab, sobald die App in Docker oder auf Heroku läuft. |
|||
|- |
|||
| Version || 20.2.0, Commit <code>5658473c</code> vom 10.08.2026: „Add missing guard around lfrChallenge for safe mode“, sollte also den sicheren Modus verbessern |
|||
|-. |
|||
| Warum fester Stand || Sonst wäre unklar, ob ein Unterschied zwischen Läufen an der KI oder am Code liegt. |
|||
|} |
|||
== Versuchsdurchführung == |
|||
=== Warum dieses Projekt? === |
|||
Juice Shop enthält einen '''Lösungsschlüssel''': Die Datei <code>data/static/challenges.yml</code> listet '''116 Challenges''', also 116 beabsichtigte Schwachstellen. Das liefert eine Referenz (''ground truth''), mit der sich messen lässt, was das Werkzeug gefunden und was es übersehen hat. Ein gewöhnliches Projekt bietet so etwas nicht. Juice Shop ist zwar nicht klein, dieser Vorteil überwiegt aber. |
|||
=== Der sichere Modus (safetyMode) === |
|||
Juice Shop hat eine Einstellung <code>safetyMode</code>. Ist sie aktiv, werden etwa 19 gefährliche Challenges wie Codeausführung oder Dateizugriff abgeschaltet, sobald die Anwendung in Docker oder auf Heroku läuft. Diese Einstellung ist für einen der wichtigsten Funde (Nr. 13) entscheidend. |
|||
=== Untersuchte Version === |
|||
Alle Läufe verwenden denselben Stand: Version 20.2.0, Commit <code>5658473c</code> vom 10. August 2026 mit der Commit-Nachricht „Add missing guard around lfrChallenge for safe mode“. Dieser Commit sollte also den Schutz im sicheren Modus verbessern. |
|||
'''Warum ein fester Stand?''' Ändert sich der Code zwischen zwei Läufen, ist nicht erkennbar, ob ein Unterschied an der KI oder am Code liegt. |
|||
=== Versuchsdesign === |
|||
{| class="wikitable" |
{| class="wikitable" |
||
! Merkmal !! Lauf 1 !! Lauf 2 |
! Merkmal !! Lauf 1 !! Lauf 2 |
||
| Line 195: | Line 191: | ||
| Profil || quick || standard |
| Profil || quick || standard |
||
|- |
|- |
||
| Budget || 25 |
| Budget || 25 Aufrufe || 60 Aufrufe |
||
|- |
|- |
||
| Vorwissen || keins || Lauf 1 (nur lesend) |
| Vorwissen || keins || Lauf 1 (nur lesend) |
||
| Line 202: | Line 198: | ||
|- |
|- |
||
| Commit || 5658473c || 5658473c |
| Commit || 5658473c || 5658473c |
||
|- |
|||
| Kandidaten je Hunter || 2 || 1 |
|||
|- |
|||
| Dauer || 26 Minuten || 3 h 13 Minuten (davon 1 h 37 min Wartezeit) |
|||
|- |
|||
| colspan="3" | '''Aufrufe nach Rolle''' |
|||
|- |
|||
| Aufklärung || 4 || 4 |
|||
|- |
|||
| Hunter || 6 || 9 |
|||
|- |
|||
| Kritiker || 1 || 2 |
|||
|- |
|||
| Prüfer Phase 3 || 12 || 21 |
|||
|- |
|||
| Prüfer Phase 5 / erneute Prüfung || 1 || 21 |
|||
|- |
|||
| '''Summe erfolgreich''' || '''24 von 25''' || '''57 von 60''' |
|||
|- |
|||
| Fehlstarts durch Ratenlimit (nicht gezählt) || – || 20 |
|||
|} |
|} |
||
=== Aufträge === |
|||
== Teil 6: Lauf 1 (quick) == |
|||
'''Lauf 1:''' |
|||
=== Auftrag === |
|||
<pre> |
<pre> |
||
Run a full security audit of this codebase using the security-audit skill. |
Run a full security audit of this codebase using the security-audit skill. |
||
| Line 214: | Line 229: | ||
Output to ~/ITS/audits/juice-shop/run-1 |
Output to ~/ITS/audits/juice-shop/run-1 |
||
</pre> |
</pre> |
||
Der Auftrag enthält die ausdrückliche Bitte um ein vollständiges Audit (damit der Audit-Modus greift), Profil, Budget, die Regel „nur Quellcode“ und den Ausgabeort. |
|||
'''Lauf 2:''' |
|||
=== Ablauf === |
|||
Lauf 1 dauerte 26 Minuten und nutzte 24 von 25 Aufrufen: |
|||
{| class="wikitable" |
|||
! Rolle !! Aufrufe |
|||
|- |
|||
| Aufklärung || 4 |
|||
|- |
|||
| Hunter || 6 |
|||
|- |
|||
| abschließender Kritiker || 1 |
|||
|- |
|||
| Prüfer || 12 |
|||
|- |
|||
| erneute Prüfung eines geänderten Datensatzes || 1 |
|||
|} |
|||
'''Budgetentscheidung:''' Damit genug Aufrufe für die Validierung blieben, begrenzte der Koordinator jeden Hunter auf '''zwei Kandidaten'''. Weitere Funde wurden als „ungeprüfte Hinweise“ (''unvalidated leads'') im Ledger vermerkt, insgesamt 23. Sie sind keine Ergebnisse, sondern Ansatzpunkte für spätere Läufe. |
|||
'''Ein Prüfer korrigiert einen Hunter:''' Ein Hunter behauptete eine Pfadtraversierung unter Windows mit <code>..\</code>. Der Prüfer stellte fest, dass eine andere Bibliothek (serve-index) genau diese Form blockiert, absolute Pfade wie <code>C:\…</code> aber nicht. Er formulierte die Aussage enger und genauer, und ein dritter Agent prüfte die Änderung. Das zeigt den Nutzen der Rollentrennung. |
|||
=== Ergebnis === |
|||
* 12 Verdachtsfälle, alle <code>needs_validation</code>; |
|||
* 0 bestätigt, wie wegen der Regel „nur Quellcode“ erwartet; |
|||
* 0 verworfen; |
|||
* Coverage Ledger: 22 Einheiten, davon 11 mit Verdachtsfall, 1 blockiert, 10 zurückgestellt. |
|||
=== Eigene Kontrolle === |
|||
Die Prüfskripte wurden von Hand erneut ausgeführt, statt der Aussage des Agenten zu vertrauen: |
|||
<pre> |
|||
node .claude/skills/security-audit/validate-findings.cjs audits/juice-shop/run-1/findings.json |
|||
PASS: 12 findings valid |
|||
node .claude/skills/security-audit/validate-coverage-ledger.cjs audits/juice-shop/run-1/coverage-ledger.json |
|||
PASS: 22 coverage units valid |
|||
</pre> |
|||
== Teil 7: Lauf 2 (standard) == |
|||
=== Start über /security-audit === |
|||
Beim zweiten Lauf lud Claude Code den Skill nicht selbstständig. Eine lokale Einstellung in <code>.claude/settings.local.json</code> hatte ihn auf „nur vom Benutzer aufrufbar“ (''user-invocable only'') gesetzt. Der Lauf wurde deshalb ausdrücklich mit dem Skill-Befehl gestartet: |
|||
<pre> |
<pre> |
||
/security-audit Full audit of ~/ITS/targets/juice-shop. |
/security-audit Full audit of ~/ITS/targets/juice-shop. |
||
| Line 263: | Line 238: | ||
Output: ~/ITS/audits/juice-shop/run-2 |
Output: ~/ITS/audits/juice-shop/run-2 |
||
</pre> |
</pre> |
||
Der Ort von Lauf 1 musste angegeben werden, weil der Skill frühere Läufe nur in seinem Standardordner <code>~/security-audit-skill/</code> selbst findet. |
|||
Beide Aufträge enthalten die ausdrückliche Bitte um ein vollständiges Audit (damit der Audit-Modus greift), Profil, Budget, die Regel „nur Quellcode“ und den Ausgabeort. In Lauf 2 musste der Ort von Lauf 1 angegeben werden, da der Skill frühere Läufe nur in seinem Standardordner <code>~/security-audit-skill/</code> selbst findet. |
|||
=== Ratenlimit: 20 Agenten abgebrochen === |
|||
In Phase 3 startete der Koordinator etwa '''20 Agenten gleichzeitig''' (19 Prüfer und einen Kritiker). Das Pro-Abonnement hat ein Sitzungslimit (''rate limit''); es wurde überschritten, und alle 20 Agenten wurden beendet, bevor sie ein Ergebnis lieferten (HTTP 429). |
|||
Der Skill riet nicht, sondern hielt an und fragte, wie die Fehlstarts auf das Budget anzurechnen seien. Er bot drei Möglichkeiten an: nicht anrechnen und neu starten, streng anrechnen und den Lauf als unvollständig beenden, oder das Budget erhöhen. Entschieden wurde: '''nicht anrechnen''', aber offen in <code>run-metadata.json</code> und im Bericht dokumentieren. Nach dem Zurücksetzen des Limits wurden die Agenten '''in Gruppen von höchstens fünf''' neu gestartet. |
|||
'''Begründung:''' Das Budget misst nützliche Prüfarbeit. Die abgebrochenen Agenten haben keine Arbeit geleistet; sie scheiterten an der Grenze des Abonnements, nicht am Werkzeug. |
|||
=== Sicherheitsfilter beim Bericht === |
|||
Beim Schreiben von <code>REPORT.md</code> hielt ein Sicherheitsfilter (''safety classifier'') den ersten Entwurf an, vermutlich wegen zu konkreter Angriffsdetails. Der Agent schrieb den Bericht daraufhin auf einer höheren Ebene neu, mit Übersichtstabellen und Korrekturvorschlägen, aber ohne Angriffsdaten. Die vollständigen Spuren blieben in <code>NEEDS-VALIDATION.md</code>. |
|||
=== Gebundenes Budget === |
|||
Die 12 Verdachtsfälle aus Lauf 1 brauchten je zwei Prüfer (Phase 3 und Phase 5), also 24 der 60 Aufrufe. Für Neues blieb wenig übrig, deshalb durfte jeder Hunter nur '''einen''' Kandidaten einreichen. 33 Ursachen blieben als ungeprüfte Hinweise im Ledger. |
|||
=== Kennzahlen === |
|||
{| class="wikitable" |
|||
! Rolle !! Aufrufe |
|||
|- |
|||
| Aufklärung || 4 |
|||
|- |
|||
| Hunter || 9 |
|||
|- |
|||
| Kritiker || 2 |
|||
|- |
|||
| Prüfer Phase 3 || 21 |
|||
|- |
|||
| Prüfer Phase 5 || 21 |
|||
|- |
|||
| '''Summe erfolgreich''' || '''57 von 60''' |
|||
|- |
|||
| Fehlstarts durch Ratenlimit (nicht gezählt) || 20 |
|||
|} |
|||
* Dauer: 3 Stunden 13 Minuten, davon 1 Stunde 37 Minuten Modellzeit, der Rest Wartezeit. |
|||
* '''21 Verdachtsfälle:''' Alle 12 aus Lauf 1 kamen '''mit demselben Urteil''' zurück, 9 sind neu. Von den neuen waren 5 in Lauf 1 schon als ungeprüfte Hinweise notiert, 4 sind neue Ursachen. |
|||
* Coverage Ledger: 53 Einheiten, davon 4 abgedeckt, 21 mit Verdachtsfall, 20 blockiert, 8 zurückgestellt. |
|||
[[File:Juice-Shop_Coverage-Ledger_Lauf1_vs_Lauf2.png|thumb|center|800px|Status der Prüfeinheiten im Coverage Ledger in beiden Läufen]] |
|||
Lauf 2 legte mehr als doppelt so viele Einheiten an. Der größte Teil der neuen Einheiten ist aber ''blockiert'': Die Hunter fanden dort Hinweise, für deren Prüfung das Budget nicht reichte. Lauf 2 brachte also '''mehr Breite, aber keinen zusätzlichen Beweis'''. |
|||
== Durchführung == |
|||
'''Lauf 1''' dauerte 26 Minuten und nutzte 24 von 25 Aufrufen (4 Aufklärung, 6 Hunter, 1 Kritiker, 13 Prüfer). Um Budget für die Validierung zu behalten, begrenzte der koordinierende Agent jeden Hunter auf zwei Kandidaten, 23 weiter Ursachen blieben als ungeprüfte Hinweise im Ledger. Ein Prüfer widerlegte die ursprüngliche Angriffsidee eines Hunter und präzisierte die Aussage. |
|||
'''Lauf 2''' dauerte 3 Stunden 13 Minuten und nutzte 57 von 60 Aufrufen (4 Aufklärung, 9 Hunter, 2 Kritiker, 42 Prüfer). Drei Ereignisse prägten ihn: |
|||
* '''Ratenlimit:''' Rund 20 gleichzeitig gestartete Agenten wurden vom Sitzungslimit des Pro-Abonnements abgebrochen. Der Skill hielt an und fragte nach. Die Fehlstarts wurden nicht auf das Budget angerechnet, aber offengelegt, und die Agenten in Fünfergruppen neu gestartet. |
|||
* '''Budgetbindung:''' Die 12 übernommenen Verdachtsfälle aus Lauf 1 banden 24 Prüferaufrufe. Jeder Hunter durfte daher nur einen Kandidaten einreichen; 33 Ursachen blieben ungeprüft. |
|||
* '''Sicherheitsfilter:''' Der erste Berichtsentwurf wurde angehalten und ohne konkrete Angriffsdaten neu geschrieben. |
|||
== Ergebnisse == |
== Ergebnisse == |
||
=== Überblick === |
=== Überblick === |
||
[[File:Juice-Shop_Coverage-Ledger_Lauf1_vs_Lauf2.png|800px|thumb|left|Status der Prüfeinheiten: Lauf 2 prüfte deutlich mehr Einheiten, die meisten neuen blieben aber blockiert, weil das Budget die Validierung nicht abdeckte.]] |
|||
{| class="wikitable" |
{| class="wikitable" |
||
! Kennzahl !! Lauf 1 !! Lauf 2 |
! Kennzahl !! Lauf 1 !! Lauf 2 |
||
|- |
|- |
||
| |
| Geprüfte Verdachtsfälle (<code>needs_validation</code>) || 12 || 21 (12 übernommen, 9 neu) |
||
|- |
|- |
||
| Bestätigt / verworfen || 0 / 0 || 0 / 0 |
| Bestätigt / verworfen || 0 / 0 || 0 / 0 |
||
| Line 326: | Line 256: | ||
|- |
|- |
||
| Prüfeinheiten im Ledger || 22 || 53 |
| Prüfeinheiten im Ledger || 22 || 53 |
||
|- |
|||
| davon covered / candidate / blocked / deferred || 0 / 11 / 1 / 10 || 4 / 21 / 20 / 8 |
|||
|- |
|- |
||
| Prüfskripte (selbst nachgeprüft) || bestanden || bestanden |
| Prüfskripte (selbst nachgeprüft) || bestanden || bestanden |
||
|} |
|} |
||
Lauf 2 brachte vor allem '''mehr Breite, aber keinen zusätzlichen Beweis'''. Die Ergebnisse sind stabil: Alle 12 Fälle aus Lauf 1 kamen mit demselben Urteil zurück. Von den 9 neuen Fällen waren 5 in Lauf 1 schon als ungeprüfte Hinweise notiert, 4 sind neue Ursachen. |
|||
[[File:Juice-Shop_Coverage-Ledger_Lauf1_vs_Lauf2.png|800px|thumb|center|Status der Prüfeinheiten: Lauf 2 prüfte deutlich mehr Einheiten, die meisten neuen blieben aber blockiert, weil das Budget die Validierung nicht abdeckte.]] |
|||
Lauf 2 brachte vor allem '''mehr Breite, aber keinen zusätzlichen Beweis'''. Die Ergebnisse sind stabil: Alle 12 Fälle aus Lauf 1 kamen mit demselben Urteil zurück. Von den 9 neuen Fällen waren 5 in Lauf 1 schon als ungeprüfte Hinweise notiert, 4 sind neue Ursachen. |
|||
| Line 389: | Line 321: | ||
|} |
|} |
||
=== Vergleich mit dem Lösungsschlüssel === |
|||
Besondersauffällig ist '''Nr. 13''' Der neueste Commit fügt einen Schalter für den '''sicheren Modus''' nur in einem Codezweig ein, im anderen fehlen Sperrliste und Kürzung. Dies ist eine Regression genau in dem Modus, der die Anwendung absichern soll. '''Nr. 3''' erlaubt Codeausführung über einen anonymen Upload, wofür es keine Challenge gibt. Nach einer Bestätigung zur Laufzeit wären beide nach Juice Shops <code>SECURITY.md</code> vertaulich an den Maintainer zu melden. |
|||
* '''Nach Lauf 1:''' ca. 29 von 116 Challenges gemeldet (ca. 25 %) |
|||
* '''Nach beiden Läufen:''' ca. 37 von 116 Challenges gemeldet (ca. 32 %) |
|||
Warum der Anteil niedrig ist: Viele Challenges sind durch Lesen von Code grundsätzlich nicht auffindbar. Bezogen auf die im Code auffindbaren Challenges wäre der Anteil höher. |
|||
'''Bemerkenswert:''' Beide Läufe zusammen fanden '''12 Verdachtsfälle außerhalb des Katalogs''' (oder nur teilweise darin). Einer davon (Nr. 7) erwies sich später als falsch. |
|||
== Verifikation der Ergebnisse == |
|||
=== Die vier wichtigsten Verdachtsfälle === |
|||
Dieser Teil beantwortet die vierte Seminarfrage. Unterschieden werden '''drei Ebenen''': |
|||
'''Nr. 13: Unvollständiger Schutz im sicheren Modus.''' Der untersuchte Commit sollte laut seiner Nachricht eine fehlende Absicherung für den sicheren Modus ergänzen. Der Entwickler fügte eine Bedingung in den <code>if</code>-Zweig ein: „Diesen Teil nicht ausführen, wenn die Challenge abgeschaltet ist.“ Der <code>else</code>-Zweig blieb jedoch unverändert und reicht den vom Benutzer gesendeten Wert <code>layout</code> weiterhin an die Template-Engine (hbs) weiter. Sperrliste und Kürzung der Antwort gab es zudem '''nur''' im <code>if</code>-Zweig. Gerade der Modus, der schützen soll, öffnet damit den Weg ohne Einschränkungen. Das ist eine echte Regression im neuesten Commit, die regelbasierte Werkzeuge kaum finden würden. |
|||
'''Nr. 3: Codeausführung über YAML-Upload.''' Juice Shop nutzt js-yaml in Version 3. Dort verwendet <code>load</code> das vollständige Schema, das bestimmte Tags in '''echte JavaScript-Funktionen''' umwandelt. Anschließend ruft der Code <code>JSON.stringify</code> auf das Ergebnis auf, wodurch eine dieser Funktionen automatisch ausgeführt wird. Der Upload ist ohne Anmeldung erreichbar. Eine passende Challenge gibt es nicht. |
|||
'''Nr. 8: Passwort-Hashes auf der Fotowand.''' Der öffentliche Endpunkt <code>GET /rest/memories</code> liefert zu jedem Foto die '''vollständigen''' Benutzerdaten des Besitzers, einschließlich Passwort-Hash. An anderen Stellen blendet der Code diese Felder bewusst aus; die Preisgabe hier ist also nicht beabsichtigt. |
|||
'''Nr. 1 und 2: Anmeldetickets für beliebige Benutzer.''' Der JWT-Signierschlüssel steht im Code, und dieselbe Datei ist unter <code>/infrastructure</code> öffentlich abrufbar. Das ist beabsichtigt. Die eigene Prüfung ergab zusätzlich, dass die alte Bibliothek auch Tokens '''ganz ohne Signatur''' (<code>alg: none</code>) akzeptiert. |
|||
Juice Shop bittet in seiner <code>SECURITY.md</code>, Lücken außerhalb der Challenges '''vertraulich''' zu melden. Nr. 13 und Nr. 3 wären nach einer Bestätigung zur Laufzeit Kandidaten dafür. |
|||
=== Vergleich mit dem Lösungsschlüssel === |
|||
{| class="wikitable" |
{| class="wikitable" |
||
! |
! Ebene !! Prüfung !! Stand !! Ergebnis |
||
|- |
|- |
||
| 1. Format || Entsprechen die Dateien Schema und Regeln? || durchgeführt || beide Skripte bestanden, in beiden Läufen, '''sagt nichts über die Echtheit einer Lücke''' |
|||
| nach Lauf 1 || ca. 29 von 116 || ca. 25 % |
|||
|- |
|- |
||
| 2. Quellcode || Existieren die zitierten Stellen und tun sie, was behauptet wird? || durchgeführt, nur lesend || 320 von 320 Referenzen korrekt; 5 offene Fragen geklärt, 1 Fall widerlegt |
|||
| nach beiden Läufen || ca. 37 von 116 || ca. 32 % |
|||
|- |
|||
| 3. Laufzeit || Funktioniert der Angriff auf einer laufenden Kopie? || nicht durchgeführt || erfordert eine isolierte Umgebung |
|||
|} |
|} |
||
=== Eigene Kontrolle der Prüfskripte === |
|||
'''Warum der Anteil niedrig ist:''' Viele Challenges sind durch Lesen von Code grundsätzlich nicht auffindbar, etwa die Ortsbestimmung eines Fotos, eine in einem Bild versteckte Nachricht, das Erraten eines schwachen Passworts oder versteckte Easter Eggs. Bezogen auf die im Code auffindbaren Challenges wäre der Anteil höher; diese Abgrenzung steht noch aus. Die Zuordnung wurde von Hand vorgenommen und ist daher eine Näherung. |
|||
Die Skripte wurden von Hand erneut ausgeführt, statt der Aussage des Agenten zu vertrauen (hier Lauf 1, Lauf 2 ebenfalls bestanden): |
|||
<pre> |
|||
node .claude/skills/security-audit/validate-findings.cjs audits/juice-shop/run-1/findings.json |
|||
PASS: 12 findings valid |
|||
node .claude/skills/security-audit/validate-coverage-ledger.cjs audits/juice-shop/run-1/coverage-ledger.json |
|||
PASS: 22 coverage units valid |
|||
</pre> |
|||
=== Der widerlegte Fall (Nr. 7) === |
|||
'''Bemerkenswert:''' Beide Läufe zusammen fanden '''12 Verdachtsfälle außerhalb des Katalogs''' (oder nur teilweise darin). Einer davon (Nr. 7) erwies sich später als falsch. |
|||
* '''Die Behauptung:''' Ein Hunter meinte in Lauf 2, die Benutzerdatensätze seien gegen PUT und DELETE geschützt, vielleicht aber nicht gegen PATCH. Akzeptiere die Bibliothek finale-rest PATCH, könne jeder Besucher Passwort oder Rolle beliebiger Benutzer ändern. |
|||
* '''Die Prüfer:''' Zwei unabhängige Prüfer markierten den Fall korrekt als <code>needs_validation</code>. Sie benannten die offene Frage: „Registriert die Bibliothek eine PATCH-Route?“ Ohne den Bibliothekscode konnten sie sie aber nicht beantworten. |
|||
* '''Die Tatsache:''' finale-rest 1.2.2 registriert Aktualisierungen standardmäßig nur für <code>put</code>, außer die Option <code>updateMethod</code> ist gesetzt. Juice Shop setzt sie nicht. '''Eine PATCH-Route existiert nicht.''' |
|||
* '''Die Lehre:''' Das Werkzeug war '''ehrlich''' und benannte seine Wissenslücke, trotzdem war der Fall falsch. '''Genauigkeit muss gemessen, nicht angenommen werden.''' In 33 Prüfurteilen (12 + 21) wurde kein Kandidat verworfen, obwohl mindestens einer falsch war. Fehlen Informationen, neigen die Prüfer offenbar zur Nachsicht. |
|||
=== |
=== Warum keine Laufzeitprüfung? === |
||
* Juice Shop ist absichtlich gefährlich und sollte nicht auf einem privaten Rechner laufen. |
|||
Nach Lauf 1 erschienen ca. 29, nach beidenLäufen ca. 37 der Challenges (rund 32 %) als Verdachtsfall, ungeprüfter Hinweis oder Härtungshinweis. Viele Challenges sind durch Code-Lesen grundsätzlich nicht auffindbar (z. B. Foto-Geolokalisierung, Steganografie, schwache Passwörter). Dafür fanden die Läufe '''12 Verdachtsfälle außerhalb des Katalogs''', von denen einer (Nr. 7) später widerlegt wurde. |
|||
* macOS bietet die geforderte Sandbox nicht; der Skill selbst verweigert die Ausführung. |
|||
* Ziel des Seminars ist die Bewertung des '''Ansatzes''', nicht die Behebung der Lücken. |
|||
<code>NEEDS-VALIDATION.md</code> enthält für jeden Fall einen fertigen Prüfplan, meist auf Basis der Projekttests, die Grundlage für einen späteren Lauf mit Ausführung. |
|||
== Stärken, Schwächen und Kosten == |
|||
== Verifikation der Ergebnisse == |
|||
{| class="wikitable" |
{| class="wikitable" |
||
! Stärken !! Schwächen |
|||
! Ebene !! Prüfung !! Ergebnis |
|||
|- |
|- |
||
| '''Genau:''' keine von 320 Code-Referenzen erfunden || '''Keine Bestätigung ohne Sandbox:''' auf einem Mac bleibt jedes Ergebnis ein Verdacht |
|||
| 1. Format || Ausgabe entspricht Schema und Ledger-Regeln || beide Prüfskripte bestanden (z. B. <code>PASS: 21 findings valid</code>); sagt nichts über echte Fehler |
|||
|- |
|- |
||
| '''Ehrlich:''' kein Schweregrad ohne Beweis; „keine bestätigten Funde“ heißt ausdrücklich nicht „sicher“ || '''Fehlender Bibliothekscode:''' in Minuten klärbare Fragen blieben offen |
|||
| 2. Quellcode || Zitierte Stellen existieren und tun, was behauptet wird || '''320 von 320''' Referenzen korrekt; 5 offene Fragen geklärt, 1 Fall widerlegt |
|||
|- |
|||
| '''Stabil:''' alle Ergebnisse aus Lauf 1 kehrten in Lauf 2 wieder || '''Nachsichtige Prüfer:''' 0 von 33 Urteilen verworfen, trotzdem war einer falsch |
|||
|- |
|||
| '''Über das Lehrbuch hinaus:''' 12 Fälle außerhalb des Katalogs, darunter eine Regression im neuesten Commit || '''Budget bestimmt das Ergebnis:''' 23 bzw. 33 Ursachen blieben ungeprüft, abhängig von der Budgetplanung, nicht vom Code |
|||
|- |
|||
| '''Gegenseitige Prüfung wirkt:''' ein Prüfer korrigierte einen Hunter|| '''Hoher Ressourcenbedarf:''' 20 parallele Agenten übersteigen das Pro-Limit |
|||
|- |
|||
| '''Sichtbare Lücken:''' das Ledger zeigt, was nicht geprüft wurde || '''Nicht deterministisch:''' ein Lauf ist eine Stichprobe, keine Messung |
|||
|- |
|||
| '''Sicheres Scheitern:''' bei Ratenlimit und Berechtigungsproblem hielt das Werkzeug an und fragte nach || |
|||
|} |
|} |
||
=== Kosten === |
|||
'''Vorgehen auf Ebene 2:''' Jede zitierte Datei und Zeile wurde geprüft, also ausgewählte Stellen wurden von Hand gelesen. Wo ein Fall an einer Frage zum Bibliotheksverhalten hing, wurde das Paket mit <code>npm pack</code> geladen und nur gelesen, nicht ausgeführt: |
|||
== Teil 9: Verifikation der Ergebnisse == |
|||
Dieser Teil beantwortet die vierte Seminarfrage. Unterschieden werden '''drei Ebenen''': |
|||
{| class="wikitable" |
{| class="wikitable" |
||
! |
! Posten !! Lauf 1 !! Lauf 2 |
||
|- |
|- |
||
| Dauer || 26 Minuten || 3 Stunden 13 Minuten |
|||
| 1. Format || Entsprechen die Dateien Schema und Regeln? || durchgeführt || beide Skripte bestanden, in beiden Läufen; '''sagt nichts über die Echtheit einer Lücke''' |
|||
|- |
|- |
||
| Agentenaufrufe || 24 || 57, dazu 20 Fehlstarts |
|||
| 2. Quellcode || Existieren die zitierten Stellen und tun sie, was behauptet wird? || durchgeführt, nur lesend || 320 von 320 Referenzen korrekt; 5 offene Fragen geklärt, 1 Fall widerlegt |
|||
|- |
|- |
||
| Geschätzte Kosten || nicht gemessen || 51,65 USD |
|||
| 3. Laufzeit || Funktioniert der Angriff auf einer laufenden Kopie? || nicht durchgeführt || erfordert eine isolierte Umgebung |
|||
|- |
|||
| Kosten je neuem Verdachtsfall || – || ca. 5,70 USD |
|||
|} |
|} |
||
== Fazit und nächste Schritte == |
|||
'''Der Cloudflare security-audit skill ist heute ein genauer und ehrlicher „Generator von Verdachtsfällen“, aber noch keine „Urteilsmaschine“.''' Er findet echte, nachvollziehbare Probleme, auch außerhalb jedes Katalogs, und sagt offen, was er nicht beweisen kann. Aus einem Verdachtsfall wird erst durch Ausführung in einer isolierten Umgebung oder durch einen prüfenden Menschen ein Befund, genau dort liegen die größten Kosten. |
|||
Die Prüfung fand in einer getrennten Cloud-Umgebung statt, unabhängig vom eigenen Rechner und ausschließlich lesend: |
|||
# Juice Shop wurde auf genau dem Commit <code>5658473c</code> ausgecheckt. |
|||
# Ein Skript prüfte jede Angabe „Datei:Zeile“ aus <code>findings.json</code>. Ergebnis: '''110 von 110''' in Lauf 1 und '''210 von 210''' in Lauf 2. '''Keine erfundene Datei, keine erfundene Zeile.''' Das war wichtig, weil Halluzinationen die größte Sorge waren. |
|||
# Für die meisten Verdachtsfälle wurden die entscheidenden Codezeilen von Hand gelesen. |
|||
# Viele Fälle hingen an einer Frage zum Verhalten einer Bibliothek. Die Agenten konnten sie nicht klären, weil die Abhängigkeiten (<code>node_modules</code>) nicht installiert waren und der Skill eine Installation verbietet. Die Bibliotheken wurden deshalb mit <code>npm pack</code> heruntergeladen, was den Code lädt, ohne ihn auszuführen, und anschließend gelesen. |
|||
=== Ergebnisse aus dem Bibliothekscode === |
|||
{| class="wikitable" |
{| class="wikitable" |
||
! |
! Seminarfrage !! Antwort |
||
|- |
|- |
||
| Welche Werkzeuge sind geeignet? || Der Skill eignet sich gut für belastbare Verdachtsfälle. Ein Vergleich mit klassischer statischer Analyse steht noch aus. |
|||
| Nr. 13 || Liest die Template-Engine <code>layout</code> aus den Optionen? || hbs 4.3.1 || ja, ohne Pfadbegrenzung → '''gestützt''' |
|||
|- |
|- |
||
| Wie funktioniert es? || Ein Koordinator zerlegt das Projekt in Einheiten, Hunter suchen parallel, unabhängige Prüfer versuchen zu widerlegen, feste Skripte prüfen die Ausgabe. |
|||
| Nr. 3 || Erzeugt <code>load</code> ausführbare Funktionen? || js-yaml 3.15.2 || ja (<code>new Function</code>) → '''gestützt''' |
|||
|- |
|- |
||
| Verstehen und verifizieren? || Verstehen ja, am Quellcode weitgehend, zur Laufzeit noch nicht |
|||
| Nr. 2 || Wird der Algorithmus aus dem Token-Kopf übernommen? || jsonwebtoken 0.4.0 → jws 0.2.6 → jwa 0.0.1 || ja, auch „none“ mit leerer Signatur → '''gestützt''' |
|||
|- |
|- |
||
| Stärken, Schwächen, Kosten? || genau, ehrlich, stabil. Ohne Sandbox keine Bestätigung. Budgetabhängig, ca. 52 USD geschätzt für Lauf 2 |
|||
| Nr. 4 || Werden <code>../</code>-Pfade aus dem Archiv bereinigt? || unzipper 0.12.5 || nein; der Schutz steckt nur in <code>extract()</code>, das Juice Shop nicht nutzt → '''gestützt''' |
|||
|- |
|||
| Nr. 7 || Gibt es eine PATCH-Route? || finale-rest 1.2.2 || nein, Aktualisierungen nur über PUT → '''widerlegt''' |
|||
|} |
|} |
||
'''Nächste Schritte''' (jede Option verändert genau eine Größe): |
|||
=== Beispiel: Ein Verdachtsfall ist kein Befund (Nr. 7) === |
|||
# '''Ausführung in einer isolierten Linux-VM:''' Der Skill kann Verdachtsfälle dort bestätigen oder verwerfen. Erst damit lässt sich die Genauigkeit messen. |
|||
'''Die Behauptung:''' In Lauf 2 meinte ein Hunter, die Benutzerdatensätze seien gegen PUT und DELETE geschützt, vielleicht aber nicht gegen PATCH. Akzeptiere die REST-Bibliothek finale-rest PATCH, könne jeder Besucher Passwort oder Rolle beliebiger Benutzer ändern. |
|||
# '''Ein zweites, kleines reales Projekt:''' zeigt, ob sich die Ergebnisse von einer Trainingsanwendung auf echten Code übertragen lassen, entspricht am ehesten der Vorgabe „eher kleine Projekte“. |
|||
'''Die Prüfer:''' Zwei unabhängige Prüfer behielten den Fall und markierten ihn korrekt als <code>needs_validation</code>. Sie benannten genau, was fehlte: „Registriert die Bibliothek eine PATCH-Route?“ Beantworten konnten sie es nicht, weil der Bibliothekscode nicht vorhanden war. |
|||
'''Die Tatsache:''' Laut Code registriert finale-rest 1.2.2 Aktualisierungen standardmäßig nur für <code>put</code>, außer die Option <code>updateMethod</code> wird gesetzt, und Juice Shop setzt sie nicht. '''Eine PATCH-Route existiert nicht''', der Verdachtsfall ist falsch. |
|||
'''Die Lehre:''' Das Werkzeug war '''ehrlich''' und hat genau benannt, was es nicht weiß. Trotzdem war der Fall falsch. '''Die Genauigkeit darf man nicht annehmen, man muss sie messen.''' Zudem haben die Prüfer in 33 Entscheidungen keinen einzigen Kandidaten verworfen, obwohl mindestens einer falsch war. Fehlen ihnen Informationen, neigen sie offenbar zur Nachsicht. |
|||
=== Warum keine Laufzeitprüfung? === |
|||
* Juice Shop ist absichtlich gefährlich und sollte nicht auf einem privaten Rechner laufen. |
|||
* macOS bietet die geforderte Sandbox nicht; der Skill selbst verweigert die Ausführung. |
|||
* Ziel des Seminars ist die Bewertung des '''Ansatzes''', nicht die Behebung von Lücken in Juice Shop. |
|||
Für jeden Verdachtsfall enthält <code>NEEDS-VALIDATION.md</code> einen fertigen lokalen Prüfplan, meist auf Basis der vorhandenen Tests des Projekts. Diese Pläne sind die Grundlage für einen späteren Lauf mit Ausführung. |
|||
== Quellen == |
|||
=== Antwort auf die vierte Seminarfrage === |
|||
* Cloudflare: ''security-audit-skill''. [https://github.com/cloudflare/security-audit-skill github.com/cloudflare/security-audit-skill] |
|||
* '''Verstehen: ja.''' Jeder Verdachtsfall nennt Angreifer, Eingabe, fehlende Kontrolle, Codespur, fehlende Information und Prüfplan. |
|||
* Cloudflare Blog: ''Build your own vulnerability harness''. [https://blog.cloudflare.com/build-your-own-vulnerability-harness blog.cloudflare.com] |
|||
* '''Am Quellcode verifizieren: weitgehend.''' Alle Referenzen stimmen; der Bibliothekscode klärte fünf Fragen und widerlegte einen Fall. |
|||
* OWASP Juice Shop, Commit 5658473c, inkl. <code>challenges.yml</code>. [https://github.com/juice-shop/juice-shop github.com/juice-shop/juice-shop] |
|||
* '''Zur Laufzeit verifizieren: noch nicht.''' |
|||
Latest revision as of 14:39, 10 October 2026
Einleitung
Große Sprachmodelle können Code lesen, Zusammenhänge über viele Dateien hinweg verfolgen und Werkzeuge bedienen. Damit liegt es nahe, sie für die Suche nach Sicherheitslücken einzusetzen. Offen ist, wie belastbar ihre Ergebnisse sind, denn ein falscher Befund ist in der Sicherheitsanalyse teuer.
Der Bericht folgt den vier Fragen:
- Welche Werkzeuge sind verfügbar und geeignet?
- Wie funktioniert eine KI-Agent-basierte Sicherheitsanalyse?
- Können die gefundenen Schwachstellen verstanden und verifiziert werden?
- Wo liegen Stärken, Schwächen und Kosten?
Werkzeugfamilien
- Klassische statische Analyse (SAST) wie Semgrep oder CodeQL ist schnell und reproduzierbar, findet aber vor allem Muster, die vorher als Regel formuliert wurden.
- KI-Ageten wie Claude Code lesen und durchsuchen Code selbstständig. Sie erkennen auch Logikfehler über Dateigrenzen hinweg, arbeiten aber nicht deterministisch.
Ein Skill ist ein Ordner mit Anweisungen, den ein KI-Agent bei Bedarf lädt und der festlegt, wie der Agent eine Aufgabe erledigt.
Der Cloudflare security-audit skill
Steckbrief
| Merkmal | Beschreibung |
|---|---|
| Herkunft | Cloudflare, großer Anbieter für den Schutz von Websites, auf GitHub unter MIT-Lizenz veröffentlicht |
| Bedeutung | Laut Blogartikel „Build your own vulnerability harness“ Ausgangspunkt für Cloudflares interne Schwachstellensuche, später ausgebaut zu einer Pipeline über mehr als 128 Repositories |
| Form | Der Skill ist kein Scanner und kein Programm. Er ist ein Ordner skills/security-audit/ mit rund 5.300 Zeilen Anweisungen und zwei Prüfskripten
|
| Modi | Anleitungsmodus (Standard): beantwortet Sicherheitsfragen ohne Berichtsdateien. Vollständiger Audit-Modus: Dieser wird nur auf ausdrückliche Anfrage („Security Audit“, „Pen-Test“, „Full Security Review“) durchgeführt und durchläuft alle sechs Phasen. Im Projekt wird nur dieser Modus verwendet. |
Bestandteile
| Datei | Aufgabe |
|---|---|
SKILL.md |
Einstieg: Betriebsarten, Sicherheitsregeln, Profile, Budget, Schweregradskala, verbotene Fehler |
RECONNAISSANCE.md |
Phase 1: Die Aufklärung des Projekts und der Aufbau von "architecture.md" und "Coverage Ledgers" |
HUNTING.md, ATTACK-CLASSES.md |
Phase 2: Aufbau der Suchaufträge und Angriffsklassen (Injection, Zugriffskontrolle, Dateien, Kryptografie, Geschäftslogik …) |
| 10 Begleitdateien | Spezialwissen, nur bei Bedarf geladen: Web und Authentifizierung, Client-Seite, KI/LLM, Lieferkette, Cloud, Protokolle, Ressourcenerschöpfung, Datenisolation, Desktop/Mobil, Speichersicherheit |
VALIDATION-AND-REPORTING.md |
Phasen 3 bis 6: Validierung, Ausgabe, zweite Verifikation, Bericht |
report-schema.json |
festes JSON-Schema für jedes Ergebnis |
validate-findings.cjs, validate-coverage-ledger.cjs |
Node.js-Skripte, die die Ausgabe mit festen Regeln prüfen |
Warum die Prüfskripte wichtig sind: Ein Sprachmodell kann eine JSON-Datei schreiben, die richtig aussieht, aber unvollständig oder widersprüchlich ist. Die Skripte arbeiten ohne KI und lehnen etwa fehlende Felder, ungültige Pfade oder einen Schweregrad für einen unbestätigten Fund ab.
Vier Rollen
Der Skill macht aus einem Agenten ein kleines Prüfteam mit vier Rollen:
| Rolle | Name im Skill | Aufgabe |
|---|---|---|
| Koordinator | Parent | die Hauptsitzung in Claude Code; verteilt die Arbeit und schreibt als Einziger die gemeinsamen Dateien |
| Sucher | Hunter | Subagenten, die in einem zugewiesenen Codebereich und für eine Angriffsklasse nach Fehlern suchen |
| Prüfer | Verifier | neue Subagenten, die die Suche nicht kennen und jeden Fund zu widerlegen versuchen |
| Kritiker | Critic | Subagenten, die nach Codebereichen suchen, die niemand geprüft hat |
Prinzip: Wer findet, bewertet nicht. Ein Agent, der seinen eigenen Fund bewertet, neigt zur Selbstbestätigung. Jeder Subagent arbeitet in agents/<agent-id>/scratch/ und liefert strukturiertes JSON an den Koordinator.
Sechs Phasen
| Phase | Was passiert | Ergebnis |
|---|---|---|
| 1 Aufklärung reconnaissance |
Der Koordinator startet vier Agenten gleichzeitig, die nur lesen:
|
architecture.md, coverage-ledger.json
|
| 2 Suche hunting |
Hunter erhalten Prüfeinheiten samt Angriffsklassen-Anweisungen im Wortlaut und verfolgen eine Eingabe bis zur kritischen Stelle (sink, z. B. Datenbankabfrage). Ein Kritiker sucht danach Lücken, diese werden neue Einheiten, falls das Budget eine weitere Welle erlaubt. | Kandidaten als JSON |
| 3 Validierung validation |
Kern des Skills: Ein neuer Prüfer liest jede zitierte Zeile erneut, sucht übersehene Schutzmechanismen und versucht zu widerlegen. | eines von drei Urteilen |
| 4 Strukturierte Ausgabe | Urteile werden geschrieben, Prüfskripte kontrollieren das Format. | findings.json
|
| 5 Zweite Verifikation | Weitere neue Agenten prüfen die Aussagen erneut, wesentliche Änderungen prüft ein zusätzlicher Agent. | bestätigte Datensätze |
| 6 Bericht | Bericht nur aus geprüften Datensätzen; er darf kein Urteil ändern. | REPORT.md, FINDINGS-DETAIL.md, NEEDS-VALIDATION.md
|
Endbedingung: Ein Lauf endet nie mitten in einer Phase. Entweder sind alle Berichtsdateien geschrieben und beide Skripte bestanden, oder der Lauf wird mit Grund als „incomplete“ markiert.
Urteile und Schweregrad
| Urteil | Bedeutung | Schweregrad? |
|---|---|---|
confirmed |
vollständige Codespur vom Eingabepunkt zur kritischen Stelle und lokal beobachtetes Ergebnis | ja |
needs_validation |
codebasierter Verdacht, dem genau ein Fakt fehlt, mit Prüfplan | nein |
rejected |
von einem Prüfer widerlegt | nein |
Einträge mit needs_validation heißen hier Verdachtsfälle (leads). Für „confirmed“ muss der Code ausgeführt werden; fehlerhaft aussehender Code genügt nicht.
| Schweregrad (nur bestätigte Funde) | Beispiel |
|---|---|
| critical | nicht angemeldeter Angreifer führt Code aus, erhält vollen Datenbankzugriff oder übernimmt beliebige Konten |
| high | Sicherheitskontrolle vollständig umgangen, z. B. Anmeldung umgangen, fremde Daten gelesen |
| medium | echte Grenzverletzung mit begrenzter Wirkung oder seltenen Voraussetzungen |
| low | Preisgabe nicht geheimer interner Informationen |
| informational | bestätigt, aber minimale Wirkung |
Coverage Ledger
Das Coverage Ledger zerlegt das Projekt in Prüfeinheiten. Jede Einheit ist eine Kombination aus vier Teilen: Eingabepunkt × Vertrauensgrenze × Teilsystem × Angriffsklasse. Jede Prüfeinheit hat einen Status
| Status | Bedeutung |
|---|---|
planned |
geplant, noch nicht begonnen |
in_progress |
ein Hunter arbeitet daran |
covered |
geprüft, kein Fund |
candidate |
enthält einen validierten Verdachtsfall |
blocked |
geprüft, enthält aber nur ungeprüfte Hinweise |
deferred |
zurückgestellt, meist wegen des Budgets |
out_of_scope, not_applicable |
außerhalb des Umfangs bzw. nicht zutreffend |
Die meisten Werkzeuge sagen, was sie gefunden haben, aber nicht, was sie nicht geprüft haben. Das Ledger macht Lücken in der Abdeckung sichtbar. Niemand kann „alles geprüft“ behaupten, solange Einheiten zurückgestellt sind.
Fingerabdruck
Jede Grundursache erhält eine feste Kennung, den Fingerabdruck (fingerprint), z. B. juice-shop/routes/login/raw-sql-string-interpolation. Er enthält keine Zeilennummer und bleibt daher auch bei kleinen Codeänderungen gleich. Damit lassen sich Läufe vergleichen.
Profile und Budget
| Profil | Bedeutung |
|---|---|
quick |
eine Suchwelle, ein abschließender Kritiker, ein Prüfer pro Kandidat. Für einen ersten Überblick. |
standard |
Suchwellen, bis die Kritiker keine Lücken mehr finden oder das Budget aufgebraucht ist, zwei Kritiker, zwei getrennte Prüfer pro Fall |
deep |
für große, kritische Projekte: feinere Einheiten, zusätzliche unabhängige Prüfung |
Das Budget ist die Höchstzahl der Agentenaufrufe über alle Phasen. Vor der Suche reserviert der Skill Aufrufe für Kritiker und Prüfer, damit die Hunter nicht das ganze Budget verbrauchen und am Ende niemand mehr prüfen kann.
Mehrere Läufe bauen aufeinander auf
Kennt ein zweiter Lauf den Ort des ersten, liest er dessen Ledger und Ergebnisse. Er konzentriert sich dann auf zurückgestellte Einheiten und ungeprüfte Hinweise und prüft alte Ergebnisse erneut. Laut Cloudflare findet ein einzelner Lauf etwa die Hälfte dessen, was wiederholte Läufe zusammen finden.
Sicherheitsregel: ohne Sandbox keine Ausführung
Zielcode darf nur in einer vom Betriebssystem erzwungenen Sandbox laufen: kein externes Netzwerk, leere Umgebung ohne Variablen und Passwörter, Zielcode nur lesbar, Schreiben nur im eigenen Arbeitsordner, harte Grenzen für CPU, Speicher, Prozesse und Laufzeit. Fehlt eine Eigenschaft, führt der Skill nichts aus, vermerkt einen Blocker und belässt den Fund bei needs_validation. Zudem verboten: Anfragen an produktive Systeme, Installation von Abhängigkeiten, echte Zugangsdaten, Änderungen am Zielcode (Korrekturen werden nur beschrieben).
Das Zielprojekt: OWASP Juice Shop
| Merkmal | Beschreibung |
|---|---|
| Was | fiktiver Saft-Webshop, absichtlich voller Lücken, für Sicherheitstrainings |
| Technik | Server: TypeScript, Node.js, Express, SQLite (Sequelize), MarsDB (In-Memory) Oberfläche: Angular · Anmeldung: JWT |
| Warum dieses Projekt | Lösungsschlüssel data/static/challenges.yml mit 116 Challenges liefert eine Referenz (ground truth), um Treffer und Lücken des Werkzeugs zu messen. Juice Shop ist nicht klein, dieser Vorteil überwiegt aber.
|
| safetyMode | schaltet ca. 19 gefährliche Challenges (Codeausführung, Dateizugriff) ab, sobald die App in Docker oder auf Heroku läuft. |
| Version | 20.2.0, Commit 5658473c vom 10.08.2026: „Add missing guard around lfrChallenge for safe mode“, sollte also den sicheren Modus verbessern
|
| Warum fester Stand | Sonst wäre unklar, ob ein Unterschied zwischen Läufen an der KI oder am Code liegt. |
Versuchsdurchführung
| Merkmal | Lauf 1 | Lauf 2 |
|---|---|---|
| Profil | quick | standard |
| Budget | 25 Aufrufe | 60 Aufrufe |
| Vorwissen | keins | Lauf 1 (nur lesend) |
| Ausführung von Zielcode | nein | nein |
| Commit | 5658473c | 5658473c |
| Kandidaten je Hunter | 2 | 1 |
| Dauer | 26 Minuten | 3 h 13 Minuten (davon 1 h 37 min Wartezeit) |
| Aufrufe nach Rolle | ||
| Aufklärung | 4 | 4 |
| Hunter | 6 | 9 |
| Kritiker | 1 | 2 |
| Prüfer Phase 3 | 12 | 21 |
| Prüfer Phase 5 / erneute Prüfung | 1 | 21 |
| Summe erfolgreich | 24 von 25 | 57 von 60 |
| Fehlstarts durch Ratenlimit (nicht gezählt) | – | 20 |
Aufträge
Lauf 1:
Run a full security audit of this codebase using the security-audit skill. Profile: quick. Budget: 25 agent invocations. Source-only: do not execute target code; record anything that needs execution as needs_validation. Output to ~/ITS/audits/juice-shop/run-1
Lauf 2:
/security-audit Full audit of ~/ITS/targets/juice-shop. Profile: standard. Budget: 60 agent invocations. Source-only: do not execute target code; record anything needing execution as needs_validation. Prior run: ~/ITS/audits/juice-shop/run-1 (coverage-ledger.json, findings.json); do not modify run-1. Output: ~/ITS/audits/juice-shop/run-2
Beide Aufträge enthalten die ausdrückliche Bitte um ein vollständiges Audit (damit der Audit-Modus greift), Profil, Budget, die Regel „nur Quellcode“ und den Ausgabeort. In Lauf 2 musste der Ort von Lauf 1 angegeben werden, da der Skill frühere Läufe nur in seinem Standardordner ~/security-audit-skill/ selbst findet.
Ergebnisse
Überblick

| Kennzahl | Lauf 1 | Lauf 2 |
|---|---|---|
Geprüfte Verdachtsfälle (needs_validation) |
12 | 21 (12 übernommen, 9 neu) |
| Bestätigt / verworfen | 0 / 0 | 0 / 0 |
| Ungeprüfte Hinweise | 23 | 33 |
| Prüfeinheiten im Ledger | 22 | 53 |
| davon covered / candidate / blocked / deferred | 0 / 11 / 1 / 10 | 4 / 21 / 20 / 8 |
| Prüfskripte (selbst nachgeprüft) | bestanden | bestanden |
Lauf 2 brachte vor allem mehr Breite, aber keinen zusätzlichen Beweis. Die Ergebnisse sind stabil: Alle 12 Fälle aus Lauf 1 kamen mit demselben Urteil zurück. Von den 9 neuen Fällen waren 5 in Lauf 1 schon als ungeprüfte Hinweise notiert, 4 sind neue Ursachen.
Die 21 Verdachtsfälle
„Katalog“ zeigt, ob der Fall einer beabsichtigten Juice-Shop-Challenge entspricht. „Eigene Prüfung“ ist das Ergebnis meiner Quellcodeprüfung. Angriffsdaten werden bewusst nicht genannt.
| Nr. | Verdachtsfall | Katalog | Eigene Prüfung |
|---|---|---|---|
| 1 | JWT-Signierschlüssel fest im Code und öffentlich abrufbar | ja | gestützt |
| 2 | JWT-Algorithmus nicht festgelegt | ja | gestützt |
| 3 | YAML-Upload erlaubt Codeausführung | nein | gestützt |
| 4 | Zip-Slip beim Datei-Upload | ja | gestützt |
| 5 | Benutzername wird per eval ausgewertet (Template-Injection) | ja | Codezeile stimmt |
| 6 | SQL-Injection in Login und Produktsuche | ja | nicht geprüft |
| 7 | Methodensperren über PATCH umgehbar | nein | widerlegt |
| 8 | Öffentlicher Endpunkt liefert Passwort-Hashes der Fotowand | nein | Code stimmt |
| 9 | Öffentliche Zugriffsprotokolle enthalten Passwörter | teilweise | gestützt |
| 10 | SSRF über Profilbild-URL | ja | Codezeile stimmt |
| 11 | SSRF über Chatbot-Nachrichten | nein | nicht geprüft |
| 12 | JavaScript-Injection über MarsDB-$where |
ja | nicht geprüft |
| 13 | Unvollständiger Sicherheitsschalter im neuesten Commit | nein | gestützt |
| 14 | Sitzungen laufen nie ab und werden nie widerrufen | nein | Code stimmt |
| 15 | Adressen ohne Eigentümerprüfung änderbar | nein | Route stimmt |
| 16 | Bewertungen massenhaft änderbar (NoSQL) | ja | nicht geprüft |
| 17 | Datenexport schreibt fremde Texte als HTML | nein | Codezeile stimmt |
| 18 | DOM-XSS über Suchparameter | ja | Codezeile stimmt |
| 19 | Unbehandelter Fehler kann den Server beenden | nein | plausibel |
| 20 | Pfadtraversal mit Backslash (nur Windows) | nein | Codezeile stimmt |
| 21 | Chatbot-Verläufe bleiben nach Abmeldung erhalten | nein | Code stimmt |
Vergleich mit dem Lösungsschlüssel
- Nach Lauf 1: ca. 29 von 116 Challenges gemeldet (ca. 25 %)
- Nach beiden Läufen: ca. 37 von 116 Challenges gemeldet (ca. 32 %)
Warum der Anteil niedrig ist: Viele Challenges sind durch Lesen von Code grundsätzlich nicht auffindbar. Bezogen auf die im Code auffindbaren Challenges wäre der Anteil höher.
Bemerkenswert: Beide Läufe zusammen fanden 12 Verdachtsfälle außerhalb des Katalogs (oder nur teilweise darin). Einer davon (Nr. 7) erwies sich später als falsch.
Verifikation der Ergebnisse
Dieser Teil beantwortet die vierte Seminarfrage. Unterschieden werden drei Ebenen:
| Ebene | Prüfung | Stand | Ergebnis |
|---|---|---|---|
| 1. Format | Entsprechen die Dateien Schema und Regeln? | durchgeführt | beide Skripte bestanden, in beiden Läufen, sagt nichts über die Echtheit einer Lücke |
| 2. Quellcode | Existieren die zitierten Stellen und tun sie, was behauptet wird? | durchgeführt, nur lesend | 320 von 320 Referenzen korrekt; 5 offene Fragen geklärt, 1 Fall widerlegt |
| 3. Laufzeit | Funktioniert der Angriff auf einer laufenden Kopie? | nicht durchgeführt | erfordert eine isolierte Umgebung |
Eigene Kontrolle der Prüfskripte
Die Skripte wurden von Hand erneut ausgeführt, statt der Aussage des Agenten zu vertrauen (hier Lauf 1, Lauf 2 ebenfalls bestanden):
node .claude/skills/security-audit/validate-findings.cjs audits/juice-shop/run-1/findings.json PASS: 12 findings valid node .claude/skills/security-audit/validate-coverage-ledger.cjs audits/juice-shop/run-1/coverage-ledger.json PASS: 22 coverage units valid
Der widerlegte Fall (Nr. 7)
- Die Behauptung: Ein Hunter meinte in Lauf 2, die Benutzerdatensätze seien gegen PUT und DELETE geschützt, vielleicht aber nicht gegen PATCH. Akzeptiere die Bibliothek finale-rest PATCH, könne jeder Besucher Passwort oder Rolle beliebiger Benutzer ändern.
- Die Prüfer: Zwei unabhängige Prüfer markierten den Fall korrekt als
needs_validation. Sie benannten die offene Frage: „Registriert die Bibliothek eine PATCH-Route?“ Ohne den Bibliothekscode konnten sie sie aber nicht beantworten. - Die Tatsache: finale-rest 1.2.2 registriert Aktualisierungen standardmäßig nur für
put, außer die OptionupdateMethodist gesetzt. Juice Shop setzt sie nicht. Eine PATCH-Route existiert nicht. - Die Lehre: Das Werkzeug war ehrlich und benannte seine Wissenslücke, trotzdem war der Fall falsch. Genauigkeit muss gemessen, nicht angenommen werden. In 33 Prüfurteilen (12 + 21) wurde kein Kandidat verworfen, obwohl mindestens einer falsch war. Fehlen Informationen, neigen die Prüfer offenbar zur Nachsicht.
Warum keine Laufzeitprüfung?
- Juice Shop ist absichtlich gefährlich und sollte nicht auf einem privaten Rechner laufen.
- macOS bietet die geforderte Sandbox nicht; der Skill selbst verweigert die Ausführung.
- Ziel des Seminars ist die Bewertung des Ansatzes, nicht die Behebung der Lücken.
NEEDS-VALIDATION.md enthält für jeden Fall einen fertigen Prüfplan, meist auf Basis der Projekttests, die Grundlage für einen späteren Lauf mit Ausführung.
Stärken, Schwächen und Kosten
| Stärken | Schwächen |
|---|---|
| Genau: keine von 320 Code-Referenzen erfunden | Keine Bestätigung ohne Sandbox: auf einem Mac bleibt jedes Ergebnis ein Verdacht |
| Ehrlich: kein Schweregrad ohne Beweis; „keine bestätigten Funde“ heißt ausdrücklich nicht „sicher“ | Fehlender Bibliothekscode: in Minuten klärbare Fragen blieben offen |
| Stabil: alle Ergebnisse aus Lauf 1 kehrten in Lauf 2 wieder | Nachsichtige Prüfer: 0 von 33 Urteilen verworfen, trotzdem war einer falsch |
| Über das Lehrbuch hinaus: 12 Fälle außerhalb des Katalogs, darunter eine Regression im neuesten Commit | Budget bestimmt das Ergebnis: 23 bzw. 33 Ursachen blieben ungeprüft, abhängig von der Budgetplanung, nicht vom Code |
| Gegenseitige Prüfung wirkt: ein Prüfer korrigierte einen Hunter | Hoher Ressourcenbedarf: 20 parallele Agenten übersteigen das Pro-Limit |
| Sichtbare Lücken: das Ledger zeigt, was nicht geprüft wurde | Nicht deterministisch: ein Lauf ist eine Stichprobe, keine Messung |
| Sicheres Scheitern: bei Ratenlimit und Berechtigungsproblem hielt das Werkzeug an und fragte nach |
Kosten
| Posten | Lauf 1 | Lauf 2 |
|---|---|---|
| Dauer | 26 Minuten | 3 Stunden 13 Minuten |
| Agentenaufrufe | 24 | 57, dazu 20 Fehlstarts |
| Geschätzte Kosten | nicht gemessen | 51,65 USD |
| Kosten je neuem Verdachtsfall | – | ca. 5,70 USD |
Fazit und nächste Schritte
Der Cloudflare security-audit skill ist heute ein genauer und ehrlicher „Generator von Verdachtsfällen“, aber noch keine „Urteilsmaschine“. Er findet echte, nachvollziehbare Probleme, auch außerhalb jedes Katalogs, und sagt offen, was er nicht beweisen kann. Aus einem Verdachtsfall wird erst durch Ausführung in einer isolierten Umgebung oder durch einen prüfenden Menschen ein Befund, genau dort liegen die größten Kosten.
| Seminarfrage | Antwort |
|---|---|
| Welche Werkzeuge sind geeignet? | Der Skill eignet sich gut für belastbare Verdachtsfälle. Ein Vergleich mit klassischer statischer Analyse steht noch aus. |
| Wie funktioniert es? | Ein Koordinator zerlegt das Projekt in Einheiten, Hunter suchen parallel, unabhängige Prüfer versuchen zu widerlegen, feste Skripte prüfen die Ausgabe. |
| Verstehen und verifizieren? | Verstehen ja, am Quellcode weitgehend, zur Laufzeit noch nicht |
| Stärken, Schwächen, Kosten? | genau, ehrlich, stabil. Ohne Sandbox keine Bestätigung. Budgetabhängig, ca. 52 USD geschätzt für Lauf 2 |
Nächste Schritte (jede Option verändert genau eine Größe):
- Ausführung in einer isolierten Linux-VM: Der Skill kann Verdachtsfälle dort bestätigen oder verwerfen. Erst damit lässt sich die Genauigkeit messen.
- Ein zweites, kleines reales Projekt: zeigt, ob sich die Ergebnisse von einer Trainingsanwendung auf echten Code übertragen lassen, entspricht am ehesten der Vorgabe „eher kleine Projekte“.
Quellen
- Cloudflare: security-audit-skill. github.com/cloudflare/security-audit-skill
- Cloudflare Blog: Build your own vulnerability harness. blog.cloudflare.com
- OWASP Juice Shop, Commit 5658473c, inkl.
challenges.yml. github.com/juice-shop/juice-shop