Prüfung zum Registered Information Security Specialist – Frühjahr 2024 (Reiwa 6), Nachmittag, Aufgabe 1 erklärt – JWT alg=none, API-Autorisierung und vorläufige WAF-Abwehr
· Go Komura · Registered Information Security Specialist, RISS-Prüfung, API, API-Sicherheit, JWT, Authentifizierung, Autorisierung, WAF, Log4Shell, Informationssicherheit, Schwachstelle, IPA
„Wir prüfen die JWT-Signatur, also lässt sich der Benutzer-ID vertrauen.“
Diese Aussage ist nur zur Hälfte richtig.
Aufgabe 1 der Nachmittagssitzung der Prüfung zum Registered Information Security Specialist, Frühjahr 2024 (Reiwa 6), dreht sich um eine von einer Smartphone-App aufgerufene API1. Nach erfolgreicher Authentifizierung wird ein JWT ausgestellt, und mit diesem JWT werden die APIs zum Abrufen und Aktualisieren der Benutzerinformationen aufgerufen. Auf den ersten Blick ein ganz gewöhnlicher Aufbau.
Doch die Prüfung deckt die folgenden vier Probleme auf.
- Ändert man im JWT-Header
algaufnone, wird ein unsigniertes JWT akzeptiert - Behält man ein gültiges JWT bei und ändert nur
midauf eine andere Benutzer-ID, lassen sich fremde Informationen abrufen und ändern - Fügt man das nicht spezifizierte
status=paidhinzu, wird aus einem kostenlosen ein zahlender Nutzer - Der per E-Mail zugestellte vierstellige Authentifizierungscode lässt sich ohne Begrenzung der Versuchszahl per Brute-Force knacken
Alle vier wirken wie „Schwachstellen rund um die Authentifizierung“, doch die Ursache ist nicht dieselbe. Gebrochen werden die Integrität des Tokens, die Autorisierung auf Objektebene, die Autorisierung auf Eigenschaftsebene und die Begrenzung der Versuchszahl – vier verschiedene Grenzen.
In der zweiten Hälfte kommt noch ein weiteres Thema hinzu. In einer weit verbreiteten Open-Source-Bibliothek wird eine kritische Schwachstelle veröffentlicht, die es einem Angreifer erlaubt, über den Missbrauch von JNDI Lookup Code von außen auszuführen. Weder eine korrigierte Version noch eine fertige WAF-Regel existieren bislang. In der Zwischenzeit wird gefragt, wie sich die Auswirkung feststellen lässt, wo die WAF hinschauen soll und warum der WAF-Modus zunächst „Erkennung“ statt „Sperrung“ sein sollte.
Dieser Artikel stützt sich auf die offiziellen Musterlösungen2 und den Auswertungskommentar3 und ordnet nicht nur die Antwort zu jeder Teilaufgabe ein, sondern auch, warum das die Antwort ist und wie streng man das in der Praxis entwerfen sollte.
flowchart TB
accTitle: Gesamtbild der Aufgabe
accDescr: Zeigt die in jeder Phase gebrochene Vertrauensgrenze - Authentifizierungscode, JWT, API-Autorisierung, Bibliotheksschwachstelle
user[Nutzer-App]
auth[4-stelliger Auth-Code]
jwt[JWT-Ausstellung]
api[Benutzer-API]
log[Protokollausgabe]
vuln[Verwundbare Bibliothek]
ext[Externe Codeausführung]
user --> auth
auth -->|Keine Versuchsbegrenzung| jwt
jwt -->|Erlaubt alg=none| api
api -->|Vertraut mid| db1[Fremde Daten lesen/ändern]
api -->|status=paid| db2[Zahlungsstatus ändern]
api --> log
log --> vuln
vuln -->|JNDI/LDAP/HTTP| ext
Abbildung 1: Gesamtbild der Aufgabe. In jeder Phase wird eine andere Vertrauensgrenze gebrochen.
1. Zunächst das Ergebnis
- Dass eine RESTful API keinen Sitzungszustand hält, heißt zustandslos (stateless). Das bedeutet nicht, dass der Server überhaupt keine Datenbank oder keinen Nutzerzustand besitzt
- Ein vierstelliger Authentifizierungscode hat 10.000 mögliche Werte. Bei 10 Versuchen pro Sekunde gelingt der Treffer im Durchschnitt nach 5.000 Versuchen, also 500 Sekunden – kürzer als die 10-minütige Gültigkeitsdauer, sodass die Ablaufzeit allein nicht schützt
- Die Mindestmaßnahme gegen
alg=nonebesteht darin zu bestätigen, dass dasalgim JWT-Header nichtNONEist. In der Praxis sollten Sie aber die Menge der erlaubten Algorithmen serverseitig festlegen - Auch bei einem gültigen JWT darf der
midder Anfrage nicht vertraut werden. Entweder wird die Benutzer-ID im JWT mitmidabgeglichen, oder – sicherer –midwird vom Client gar nicht erst entgegengenommen und das Ziel aus dem JWT bestimmt - Das Hinzufügen von
status=paidist ein Problem vom Typ Mass Assignment, bei dem Eigenschaften außerhalb der Spezifikation direkt an das interne Objekt gebunden werden. Verwenden Sie das Aktualisierungs-DTO als Positivliste, und lassen Sie den Zahlungsstatus nie durch den Nutzer ändern - Die Musterlösung gegen Brute-Force lautet: Verarbeitung, die das Konto sperrt, sobald die Anzahl aufeinanderfolgender Fehlversuche einen Schwellenwert überschreitet. In der Praxis kommen gestaffelte Verzögerungen und quellenbezogene Kontrollen hinzu
- Um die Auswirkung einer neu veröffentlichten kritischen Schwachstelle zu bestätigen, zeichnen Sie statt eines destruktiven Befehls Zugriffe auf die
index.htmleines Testservers auf, um zu bestätigen, dass externe Codeausführung tatsächlich erreicht wird - Da die Angriffszeichenfolge in einem HTTP-Header steckt, ist das Prüfziel der WAF
Header. Als regulärer Ausdruck, der Groß-/Kleinschreibung berücksichtigt, eignet sich etwa\W[jJ][nN][dD][iI]\W - Der Vorteil, die WAF zunächst auf „Erkennung“ zu stellen, ist, dass eine Sperrung durch Fehlalarme verhindert wird. Bei einem Alarm wird geprüft, ob es sich um einen echten Angriff handelt, bevor nach der Feinabstimmung zur Sperrung gewechselt wird
- Die WAF ist nur eine vorläufige Maßnahme; die grundlegende Abhilfe ist die Aktualisierung der betroffenen Bibliothek auf eine korrigierte Version
2. Wie das Szenario auf die Teilaufgaben abgebildet wird
Schauplatz ist Unternehmen G, das einen neuen Gesundheitsdienst startet. Nutzer geben über eine Smartphone-App Angaben wie Mahlzeiten und Körpergewicht ein und erhalten eine Einschätzung des Gesundheitsrisikos sowie Ernährungsempfehlungen. Das System läuft in der Cloud und kombiniert ein API-Gateway, ereignisgesteuerte Verarbeitung und eine verwaltete Datenbank.
Das Aufgabenheft abstrahiert konkrete Produkt- und Dienstnamen. Auch dieser Artikel gibt IPAs Abbildungen und Text nicht wortgetreu wieder, sondern paraphrasiert nur die für das Verständnis der Teilaufgaben nötige Struktur.
| Teilaufgabe | Thema | Kapitel dieses Artikels |
|---|---|---|
| Teilaufgabe 1 | Eigenschaft von RESTful APIs | Kapitel 4 |
| Teilaufgabe 2(1) | Zeit zum Brute-Force des 4-stelligen Codes | Kapitel 5 |
| Teilaufgabe 2(2) | JWT alg=none |
Kapitel 6 |
| Teilaufgabe 2(3) | Zugriff auf fremde Daten über mid |
Kapitel 7 |
| Teilaufgabe 2(4) | Das Leck, das ein nicht spezifiziertes status akzeptiert |
Kapitel 8 |
| Teilaufgabe 2(5) | Gegenmaßnahmen gegen Brute-Force | Kapitel 9 |
| Teilaufgabe 3(1) | Sichere Bestätigung, dass eine Schwachstelle existiert | Kapitel 11 |
| Teilaufgabe 3(2)(3) | Wo die WAF hinschaut, und der reguläre Ausdruck | Kapitel 12 |
| Teilaufgabe 3(4) | Vorteil des Erkennungsmodus und dessen Betrieb | Kapitel 13 |
Der Auswertungskommentar merkt an, dass die Gesamterfolgsquote durchschnittlich war. Er weist aber auch darauf hin, dass die Erfolgsquote bei der Gegenmaßnahme gegen JWT-Manipulation in Teilaufgabe 2(2) und beim für den Prüfserver nötigen Mechanismus in Teilaufgabe 3(1) etwas geringer war. Beides lässt sich nicht allein mit Vokabelwissen lösen. Man muss verfolgen, welchen Wert der Angreifer geändert hat, in welche Verarbeitung er einfließt und wo er letztlich vertraut wurde.
3. Dies ist nicht nur „ein Authentifizierungsproblem“
Legt man die gesamte Aufgabe nach Vertrauensgrenzen aus, ergibt sich Folgendes.
[Benutzer-ID / Passwort]
|
v
[Prüfung des 4-stelligen Codes] ---- keine Versuchsbegrenzung ----> Brute-Force
|
v
[JWT ausstellen]
|
v
[JWT-Bibliothek] ------- erlaubt alg=none ------> Manipulation der Benutzer-ID
|
v
[Benutzer-API]
| |
| +-- reicht status komplett durch ----> Autorisierungslücke auf Eigenschaftsebene
|
+-- vertraut mid -----------------------> Autorisierungslücke auf Objektebene
[Externe Eingabe protokollieren]
|
v
[Verwundbare Bibliothek] ---- JNDI/LDAP/HTTP ------> Externe Codeausführung
Die wichtigste Unterscheidung dabei ist diese:
| Prüfung | Beantwortete Frage | In dieser Aufgabe gebrochenes Beispiel |
|---|---|---|
| Authentifizierung | Wer sind Sie | Brute-Force des 4-stelligen Codes |
| Tokenprüfung | Wurde diese Identitätsinformation manipuliert | alg=none |
| Autorisierung auf Objektebene | Darf dieser Nutzer auf diese Daten zugreifen | Austausch von mid |
| Autorisierung auf Eigenschaftsebene | Darf dieses Feld geändert werden | status=paid |
| Grenze von Eingabe zu Ausführung | Wird externe Eingabe als Befehl interpretiert | JNDI Lookup |
Eine bestandene Prüfung ist niemals ein Grund, die nächste zu überspringen. Ein Nutzer mit einem gültigen JWT darf deshalb noch lange nicht die Daten eines anderen lesen. Ein Nutzer, der seine eigenen Daten aktualisieren darf, darf deshalb noch lange nicht auch seinen Zahlungsstatus ändern.
Trennt man diese Stufen sauber, wird die Antwort zu jeder Teilaufgabe zu etwas, das man nicht mehr auswendig lernen muss.
flowchart LR
accTitle: Der Unterschied zwischen Authentifizierung und Autorisierung
accDescr: Authentifizierung bestätigt das Subjekt, Autorisierung bestätigt, was dieses Subjekt tun darf
auth[Authentifizierung<br/>wer Sie sind]
authz[Autorisierung<br/>was Sie tun dürfen]
auth --> authz
Abbildung 2: Der Unterschied zwischen Authentifizierung und Autorisierung. Authentifizierung kommt zuerst, Autorisierung ist eine eigene Prüfung.
4. Teilaufgabe 1 – Was bedeutet „zustandslos“?
Teilaufgabe 1 fragt nach einem der Entwurfsprinzipien von RESTful APIs: der Eigenschaft, keine Sitzungsverwaltung durchzuführen.
Die Antwort lautet zustandslos (stateless).
Zustandslos bedeutet, dass der Server sich den Gesprächszustand der vorherigen Anfrage nicht merken muss, weil jede Anfrage für sich allein alle für die Verarbeitung nötigen Informationen mitbringt. In dieser Aufgabe hängt die Smartphone-App bei jeder Anfrage ein JWT an den Authorization-Header. Der Server prüft dieses JWT und bestimmt daraus den Nutzer dieser Anfrage.
Ein häufiges Missverständnis besteht darin, „zustandslos“ als „der Server hält überhaupt keinen Zustand“ zu lesen. Tatsächlich hält er normalerweise Folgendes:
- Die Datenbank, die Benutzer- und Gesundheitsdaten speichert
- Den Zahlungsstatus
- Den Wert, die Gültigkeitsdauer und die Fehlerzahl des Authentifizierungscodes
- Den Signaturschlüssel des JWT
- Bei Entwürfen mit einer Widerrufsliste deren Widerrufsinformationen
- Protokolle und Prüfnachweise
Was er nicht hält, ist ein serverseitiger Sitzungszustand, der nur dazu dient, ein Gespräch fortzusetzen, und den jeder API-Aufruf als Voraussetzung braucht.
Zustandslosigkeit erhöht die Sicherheit außerdem nicht automatisch. Das JWT bei jeder Anfrage mitzusenden erleichtert zwar horizontale Skalierung, aber ein Fehler bei der JWT-Prüfung breitet sich damit ebenso gleichmäßig auf alle Knoten aus. Eine architektonische Eigenschaft und sicherheitstechnische Korrektheit sind zweierlei.
5. Teilaufgabe 2(1) – Ein 4-stelliger Code fällt im Schnitt nach 500 Sekunden
Die Authentifizierungs-API sendet, sobald Benutzer-ID und Passwort übereinstimmen, eine vierstellige Zahl per E-Mail. Stimmen anschließend Benutzer-ID und der vierstellige Code überein, wird ein JWT ausgestellt. Der Code ist ab der Erzeugung 10 Minuten gültig.
Bei der Prüfung waren 10 Versuche pro Sekunde möglich. Gefragt ist, wie viele Sekunden im Durchschnitt bis zum Durchbruch nötig sind.
Die Rechnung ist „die Hälfte des Kandidatenraums“
Eine vierstellige Zahl hat, den führenden Nullwert eingeschlossen, die folgenden 10.000 Möglichkeiten.
0000, 0001, 0002, ... , 9999
Wird der richtige Wert gleichverteilt zufällig gewählt, erreicht ein Angreifer, der der Reihe nach ohne Wiederholung durchprobiert, den Treffer im Durchschnitt nach der Hälfte des Kandidatenraums.
Durchschnittliche Versuchszahl = 10.000 / 2 = 5.000
Durchschnittliche Zeit = 5.000 / 10 Versuche pro Sekunde = 500 Sekunden
Also lautet Lücke b 500.
Im schlimmsten Fall dauert es bis zu 1.000 Sekunden, doch gefragt ist der Durchschnitt. Und die Gültigkeitsdauer des Codes beträgt 600 Sekunden – länger als die durchschnittliche Durchbruchszeit von 500 Sekunden. Deshalb wird beurteilt, dass „ein Durchbruch wahrscheinlich ist“.
flowchart LR
accTitle: Zeitgefühl für den 4-stelligen Authentifizierungscode
accDescr: 10.000 Kandidaten bei 10 Versuchen pro Sekunde ergeben im Schnitt 5.000 Versuche und 500 Sekunden, kürzer als die 600-sekündige Gültigkeitsdauer
A[10.000 Kandidaten] -->|Durchschnitt 10.000 / 2 = 5.000 Versuche| B[Durchschnittliche Durchbruchszeit 500 Sekunden]
C[Gültigkeitsdauer 600 Sekunden] -->|500 Sekunden < 600 Sekunden| D[Innerhalb der Gültigkeitsdauer durchbrechbar]
Abbildung 9: Zeitgefühl für den 4-stelligen Authentifizierungscode. Probiert man im Schnitt die Hälfte des Kandidatenraums durch, gelingt der Treffer innerhalb der Gültigkeitsdauer.
Nur die Ablaufzeit zu verkürzen, verliert bei einem kleinen Kandidatenraum trotzdem
Die Stärke eines Authentifizierungscodes bestimmt sich weder allein aus der Stellenzahl noch allein aus der Gültigkeitsdauer.
Mögliche Versuche innerhalb der Gültigkeitsdauer
= Versuche pro Sekunde x Gültigkeitsdauer
= 10 x 600
= 6.000 Versuche
Probiert man nicht wiederholte Werte der Reihe nach durch, lassen sich 60 % der 10.000 Möglichkeiten innerhalb der Gültigkeitsdauer prüfen. Eine Ablaufzeit allein genügt nicht, wenn die Anzahl der Versuche nicht begrenzt ist.
Der aktuelle NIST SP 800-63B verlangt für kurzfristige Geheimnisse bei der Out-of-Band-Authentifizierung mindestens sechs Stellen und schreibt bei weniger als 64 Bit Entropie eine Begrenzung der Versuchszahl vor. Zudem fordert er, E-Mail nicht für die Out-of-Band-Authentifizierung zu verwenden4. Die Prüfungsantwort arbeitet innerhalb der vorgegebenen Spezifikation eines vierstelligen, per E-Mail versendeten Codes, doch bei einem neuen Entwurf in der Praxis sollte diese Prämisse selbst überdacht werden.
6. Teilaufgabe 2(2) – alg=none ist das Problem, „den Angreifer die Prüfmethode wählen zu lassen“
Das JWT dieser Aufgabe besteht aus drei Teilen: Header, Payload und Signatur.
base64url(header).base64url(payload).base64url(signature)
Im Header war RS256 als Signaturalgorithmus vermerkt. Die Payload enthält Benutzer-ID, Ausstellungszeitpunkt und Ablaufdatum.
Die prüfende Person änderte die beiden folgenden Dinge.
- Das
algim Header vonRS256aufNONEändern - Die Benutzer-ID in der Payload auf einen anderen Nutzer ändern
Sendete man dieses JWT, gelang die Prüfung, und man konnte sich als jemand anderes ausgeben.
flowchart LR
accTitle: Ablauf des JWT-alg=none-Angriffs
accDescr: Ändert alg in einem gültigen JWT auf none und schreibt die Benutzer-ID um, sodass die Anfrage durchgeht
A[Gültiges JWT<br/>alg=RS256<br/>user=user01] -->|Header-alg auf none ändern| B[Manipuliertes JWT<br/>alg=none<br/>user=user02]
B -->|Überspringt Signaturprüfung| C[Server akzeptiert es<br/>als user02]
Abbildung 3: Ablauf des JWT-alg=none-Angriffs. Der Angreifer wählt den Prüfalgorithmus selbst.
none ist kein Tippfehler
RFC 7519 definiert ein „Unsecured JWT“ – ein JWT ohne Signatur und ohne Verschlüsselung, dessen alg none lautet5. Der Wert none ist also nicht etwas, das in der Spezifikation schlicht nicht existiert.
Das Problem ist, dass eine API, die nur signierte JWTs akzeptieren sollte, das vom Angreifer vorgegebene none akzeptiert hat.
Konzeptionell aufgeschrieben, sieht die verwundbare Verarbeitung so aus.
1. JWT-Header lesen
2. Das im Header stehende alg ansehen und danach die Prüfmethode wählen
3. Ist alg gleich none, die Signaturprüfung nicht durchführen
4. Der Benutzer-ID in der Payload vertrauen
Aus einer vom Angreifer kontrollierten Eingabe wird die Stärke der Sicherheit selbst ausgewählt.
Die Prüfungsantwort
Die Teilaufgabe fragt, jeweils in ≤20 Zeichen, welche Daten die korrigierte Bibliothek Q prüfen soll und welche Prüfung dabei stattfinden soll.
Die Musterlösung lautet:
| Punkt | Kern der Antwort |
|---|---|
| Zu prüfende Daten | Der im JWT-Header unter alg angegebene Wert |
| Inhalt der Prüfung | Prüfen, dass er nicht NONE ist |
Als unmittelbare Korrektur der im Aufgabentext beschriebenen Schwachstelle ist das die richtige Antwort.
In der Praxis nicht bei „alles außer NONE ist okay“ stehen bleiben
Hier muss man die Prüfungsantwort von der Empfehlung für die Praxis trennen.
RFC 8725 verlangt, dass eine JWT-Bibliothek den Aufrufer eine Menge erlaubter Algorithmen angeben lässt und dass nichts außerhalb dieser Menge verwendet werden darf6. Mit anderen Worten:
Schlechter Ansatz:
Akzeptieren, wenn token.header.alg != "none"
Guter Ansatz:
Nur akzeptieren, wenn in serverConfig.allowedAlgorithms enthalten
Beispiel: allowedAlgorithms = ["RS256"]
Nur none abzulehnen, kann trotzdem andere schwache Algorithmen oder eine Algorithmus-Verwechslung offenlassen, bei der ein Verfahren mit öffentlichem Schlüssel mit einem symmetrischen Verfahren verwechselt wird. Das Prinzip lautet: nicht die Verneinungen dessen häufen, was abgelehnt wird, sondern eng festlegen, was erlaubt ist.
Bei der JWT-Prüfung sollten Sie, je nach Verwendungszweck, mindestens auch Folgendes prüfen – nicht nur den Algorithmus.
| Punkt | Was zu prüfen ist |
|---|---|
| Signatur | Lässt sie sich mit dem erwarteten Schlüssel und Algorithmus verifizieren |
iss |
Ist es ein vertrauenswürdiger Aussteller |
aud |
Wurde das Token für diese API ausgestellt |
exp |
Liegt es innerhalb der Gültigkeitsdauer |
nbf |
Liegt es nicht vor dem „gültig ab“-Zeitpunkt |
sub oder Benutzer-ID |
Ist es ein gültiges Subjekt in der Anwendung |
| Tokentyp | Wird ein ID-Token nicht mit einem Access-Token o. Ä. verwechselt |
In dieser Aufgabe lautet der Schlüsselname in der Payload user, in der Praxis sollten Sie aber entweder den Standard sub verwenden oder die Bedeutung eines eigenen Claims klar definieren.
flowchart TB
accTitle: Sichere und unsichere JWT-Prüfung
accDescr: Unsichere Prüfung hängt von alg ab, sichere Prüfung nutzt eine serverseitige Positivliste
subgraph "Unsichere Prüfung"
D1[alg aus dem JWT-Header lesen]
D2[Akzeptieren, wenn alg gleich none ist]
D1 --> D2
end
subgraph "Sichere Prüfung"
S1[Serverseitig erlaubte Algorithmen<br/>z. B. RS256]
S2[Prüfen, ob das alg im JWT-Header<br/>in der Positivliste steht]
S3[Signatur, iss, aud, exp prüfen]
S1 --> S2 --> S3
end
Abbildung 4: Sichere und unsichere Prüfung. In der Praxis wird eine eng gefasste Menge erlaubter Algorithmen festgelegt.
Base64url ist keine Verschlüsselung
Ein weiteres bei JWTs häufiges Missverständnis: Header und Payload werden in base64url dargestellt, doch das ist keine Verschlüsselung. Jeder kann sie dekodieren und lesen.
Was die Signatur garantiert – und zwar nur, wenn sie sich korrekt verifizieren lässt –, ist, dass der Inhalt seit der Ausstellung nicht verändert wurde. Das bedeutet nicht, dass geheim zu haltende persönliche Daten in die Payload eines signierten JWT gehören.
7. Teilaufgabe 2(3) – Auch bei gültigem JWT ließ sich durch Ändern von mid fremdes lesen
Als Nächstes ein Angriff, der das JWT selbst nicht manipuliert.
Die Benutzer-API nimmt per GET oder PUT eine Benutzer-ID namens mid entgegen. Das gemeinsame Modul P ruft die zu dieser mid gehörenden Benutzerinformationen aus der Datenbank ab bzw. aktualisiert sie.
Der Aufbau des Angriffs ist einfach.
Benutzer-ID im JWT: user01 <- ein korrekt signiertes JWT
mid der Anfrage: user02 <- vom Angreifer geändert
Die Signatur des JWT ist gültig, also gelingt die Authentifizierung. Doch die API vertraut mid=user02 unverändert und liefert die Informationen von user02 zurück.
Das ist ein Lehrbuchbeispiel dessen, was die OWASP API Security Top 10 2023 Broken Object Level Authorization (BOLA) nennt. Immer wenn auf Daten über eine vom Nutzer angegebene Objekt-ID zugegriffen wird, muss die Autorisierung für genau dieses Objekt jedes Mal geprüft werden7.
flowchart LR
accTitle: Der BOLA-Angriff
accDescr: Verwendet ein gültiges JWT, ändert aber die mid der Anfrage auf eine andere Benutzer-ID
A[Angreifer] -->|JWT: user01<br/>mid: user02| B[Benutzer-API]
B -->|Vertraut mid| C[Liefert user02s Daten aus der DB]
Abbildung 5: Der BOLA-Angriff. Die Authentifizierung gelingt, die Autorisierung wurde nie geprüft.
Die Antwort der Teilaufgabe
Unterstreichung ② in Tabelle 5 fragt in ≤40 Zeichen nach der Verarbeitung, die dem Aufruf des gemeinsamen Moduls P hinzuzufügen ist.
Die Musterlösung lautet:
Verarbeitung, die prüft, ob die im JWT enthaltene Benutzer-ID mit dem Wert von mid übereinstimmt
Der Vorteil, dies im gemeinsamen Modul P zu prüfen, ist, dass sich dieselbe Autorisierung leicht sowohl auf GET als auch auf PUT anwenden lässt – und auf jede künftige API, die P nutzt. Kopiert man denselben Vergleich in jeden einzelnen Bildschirm oder Endpunkt, fehlt er irgendwo.
Sicherer entworfen ist, mid gar nicht erst entgegenzunehmen
Für eine API, die nur die eigenen Informationen des Aufrufenden abruft oder aktualisiert, ist es gar nicht nötig, eine Benutzer-ID vom Client entgegenzunehmen.
GET /users/me
Authorization: Bearer <JWT>
Serverseitig wird das Subjekt aus dem geprüften JWT entnommen.
principal = validateJwt(request.authorization)
userId = principal.subject
return repository.getUser(userId)
Für Aktualisierungen gilt dasselbe.
principal = validateJwt(request.authorization)
input = validateProfileUpdate(request.body)
repository.updateProfile(
userId = principal.subject,
name = input.name,
age = input.age
)
Eine Vergleichsprüfung schützt, wenn man sie schreibt. Ein Entwurf, der die Ziel-ID aber gar nicht erst von außen entgegennimmt, verringert die Existenz dieser Fehlerklasse selbst – dass man den Vergleich schlicht zu schreiben vergisst.
Muss ein Administrator die Benutzerinformationen einer anderen Person bearbeiten können, trennen Sie das so:
PUT /users/me für allgemeine Nutzer
PUT /admin/users/{userId} für Administratoren
Für die Administratorroute verlangen Sie separate Berechtigungen, Audit-Protokollierung und bei Bedarf eine erneute Authentifizierung. Das macht die Grenzen der Autorisierungsrichtlinie deutlich sichtbarer als „der allgemeinen Nutzer-API nur für Administratoren eine Ausnahme hinzufügen“.
flowchart LR
accTitle: Wie man BOLA verhindert
accDescr: Statt die mid der Anfrage zu nutzen, das Ziel aus dem subject des JWT bestimmen oder abgleichen
A[Nutzer] -->|GET /users/me + JWT| B[API]
B -->|sub aus JWT entnehmen| C{Falls mid vorhanden,<br/>stimmt es mit sub überein}
C -->|Übereinstimmung| D[Eigene Daten zurückgeben]
C -->|Keine Übereinstimmung| E[403 ablehnen]
B -->|Keine mid| F[DB-Suche über sub aus JWT]
Abbildung 6: Wie man BOLA verhindert. Entweder mid gar nicht entgegennehmen, oder gegen das subject des JWT abgleichen.
Authentifizierung und Autorisierung in einem Satz unterscheiden
Sowohl in der Prüfung als auch in der Praxis hilft diese Formulierung:
- Authentifizierung: wer Sie sind
- Autorisierung: was diese Person tun darf
Eine erfolgreiche JWT-Signaturprüfung bringt Sie nur so weit wie „dem Subjekt, das dieses Token darstellt, kann vertraut werden“. Ob „dieses Subjekt user02 lesen darf“, muss gesondert geprüft werden.
8. Teilaufgabe 2(4) – status=paid ist eine Autorisierungslücke auf Eigenschaftsebene
Die Spezifikation der Benutzer-API definiert die folgenden Aktualisierungsparameter.
mid Benutzer-ID
name Name
age Alter
Die prüfende Person fügte jedoch den folgenden, nicht spezifizierten Wert hinzu.
status=paid
Daraufhin wechselte der Status eines kostenlosen Nutzers zu dem eines zahlenden Nutzers.
Laut Aufgabentext validierte Dienst L die empfangenen Parameter nicht, sondern reichte alle unverändert an das gemeinsame Modul P weiter, das so gebaut war, dass es die Datenbank direkt aktualisieren konnte.
Die Antwort für Lücke c lautet gemeinsames Modul P.
flowchart TB
accTitle: Mass Assignment
accDescr: Ein nicht spezifiziertes status=paid wird hinzugefügt und vollständig auf das interne Objekt übertragen
A[API-Spezifikation<br/>mid / name / age] -->|Angreifer fügt status=paid hinzu| B[Request-Body]
B -->|Automatisch gebunden| C[Gemeinsames Modul P]
C -->|In DB gespeichert| D[Zahlungsstatus auf paid geändert]
Abbildung 7: Mass Assignment. Eine nicht spezifizierte Eigenschaft wird vollständig auf das interne Objekt übertragen.
Der Unterschied zu BOLA
Der mid-Austausch aus dem vorigen Kapitel und das jetzige Hinzufügen von status sehen sich ähnlich, doch die geschützte Granularität ist unterschiedlich.
| Schwachstelle | Was der Angreifer ändert | Was tatsächlich geprüft werden müsste |
|---|---|---|
mid-Austausch |
Das Zielobjekt | Darf dieser Nutzer auf diesen Benutzerdatensatz zugreifen |
status-Zusatz |
Eine Eigenschaft innerhalb des Objekts | Darf dieser Nutzer dieses Feld ändern |
Die OWASP API Security Top 10 2023 führt Letzteres als Broken Object Property Level Authorization und ordnet das früher als Mass Assignment bezeichnete Problem dieser Kategorie zu8.
„JSON direkt in die Entität schreiben“ ist gefährlich
Konzeptionell sieht die verwundbare Implementierung so aus.
entity = repository.find(body.mid)
bindAllProperties(entity, body)
repository.save(entity)
Auch wenn der Bildschirm nur Eingabefelder für name und age zeigt, kann ein Angreifer die HTTP-Anfrage direkt selbst bauen. Dass ein Feld in der Oberfläche fehlt, ist keine Sicherheitsgrenze.
Eine sichere Implementierung macht die aktualisierbaren Felder explizit.
input = parseExactSchema(body, fields = ["name", "age"])
entity = repository.find(authenticatedUserId)
entity.name = input.name
entity.age = input.age
repository.save(entity)
Hier zählen zwei Dinge.
- Der Eingabetyp für Aktualisierungen sollte nur die Felder enthalten, die ein Nutzer ändern darf
- Unbekannte, nicht spezifizierte Felder sollten nach Möglichkeit als Fehler abgelehnt statt stillschweigend ignoriert werden
Unbekannte Felder stillschweigend zu ignorieren verbirgt zwar, dass ein Angriff fehlschlug, lässt aber auch Implementierungsfehler des Clients und Anzeichen eines Angriffs übersehen. Ohne Kompatibilitätsgrund lässt sich mit einem strengen Schema leichter untersuchen, wenn abgelehnt wird.
flowchart TB
accTitle: Autorisierung auf Eigenschaftsebene
accDescr: Das Aktualisierungs-DTO enthält nur eine Positivliste, unbekannte Eigenschaften werden abgelehnt
subgraph "Aktualisierungs-DTO (Positivliste)"
D1["name"]
D2["age"]
end
A[Request-Body] -->|Schemaprüfung| B{Nur erlaubte<br/>Felder vorhanden}
B -->|Ja| C[name/age der Entität aktualisieren]
B -->|Nein| D[Fehler zurückgeben]
E[Zahlungsdienst<br/>verifizierte Benachrichtigung] -->|Eigener Weg| F[status=paid aktualisieren]
Abbildung 8: Autorisierung auf Eigenschaftsebene. Aktualisierbare Felder per Positivliste beschränken, Zahlungsstatus nur über einen separaten Weg ändern.
status nur aus dem Zahlungsergebnis ändern
status=paid ist kein Teil des Benutzerprofils. Es ist ein Zustand, der aus einer serverseitigen Tatsache abgeleitet wird: dass die Zahlung erfolgreich war.
Aktualisierung des Benutzerprofils
-> nur name / age änderbar
Verifizierte Benachrichtigung vom Zahlungsdienst
-> paymentId abgleichen
-> doppelte Verarbeitung verhindern
-> status auf paid ändern
Auch wenn beides in derselben Datenbankspalte gespeichert wird, sind die Berechtigung zur Änderung und der Weg der Änderung zweierlei. Verwendet man eine interne Entität unmittelbar als Eingabetyp einer externen API, verschwindet diese Grenze.
9. Teilaufgabe 2(5) – Die Gegenmaßnahme gegen Brute-Force hält die Fehlerzahl als Zustand
Gegen das Brute-Forcing des 4-stelligen Codes fragt Lücke d in Tabelle 5 in ≤30 Zeichen nach der dort einzusetzenden Verarbeitung. Der Schwellenwert ist 10.
Die Musterlösung lautet:
Verarbeitung, die das Konto sperrt, sobald die Anzahl aufeinanderfolgender Fehlversuche den Schwellenwert überschreitet
Das widerspricht nicht der Zustandslosigkeit aus Teilaufgabe 1. Den Gesprächszustand eines API-Aufrufs nicht als Serversitzung zu halten und die für eine Sicherheitsentscheidung nötige Fehlerzahl dauerhaft zu speichern, sind zwei verschiedene Dinge.
flowchart LR
accTitle: Mit und ohne Begrenzung der Versuchszahl
accDescr: Ohne Begrenzung wird der Code im Schnitt nach 500 Sekunden geknackt, eine Fehlerzahlbegrenzung bremst den Angriff drastisch
subgraph "Ohne Begrenzung"
A1[10 Versuche pro Sekunde] -->|Etwa 500 Sekunden| B1[Authentifizierung gelingt]
end
subgraph "Mit Begrenzung"
A2[Sperre nach 10 Fehlversuchen] -->|Angriffsgeschwindigkeit bricht ein| B2[Konto gesperrt]
C2[Gestaffelte Verzögerung] --> B2
end
Abbildung 10: Mit und ohne Begrenzung der Versuchszahl. Eine Fehlerzahlbegrenzung kann Brute-Force praktisch stoppen.
In der Praxis nicht allein auf „dauerhafte Sperre“ setzen
Eine kontobezogene Versuchsbegrenzung ist nötig, doch kennt ein Angreifer die Benutzer-ID einer anderen Person, kann er absichtlich zehnmal fehlschlagen lassen und so den rechtmäßigen Nutzer aussperren. In der Praxis kombiniert man deshalb Folgendes.
| Kontrolle | Rolle |
|---|---|
| Kontobezogene Fehlerzahl | Stoppt Brute-Force gegen ein einzelnes Konto |
| Gestaffelte Wartezeiten | Toleriert Tippfehler rechtmäßiger Nutzer und bremst gleichzeitig den Angriff |
| Kontrolle nach Quell-IP, Gerät, ASN usw. | Bremst Angriffe, die viele Konten mit jeweils wenigen Versuchen ausprobieren |
| Risikobasierte Beurteilung | Schränkt bei ungewöhnlicher Region, ungewöhnlichem Gerät oder Geschwindigkeit stärker ein |
| Benachrichtigung des Nutzers | Lässt Nutzer einen Angriff oder eigenen Fehler bemerken |
| Sicheres Wiederherstellungsverfahren | Verhindert, dass der Entsperrkanal selbst zum Angriffsweg wird |
Zudem darf beim erneuten Versand eines Codes die Fehlerzahl nicht auf null zurückgesetzt werden – sonst kann ein Angreifer sein Versuchskontingent bei jedem Aufruf der Neuversand-API wieder auffüllen. Auch der aktuelle NIST SP 800-63B verlangt, die Fehlerzahl selbst bei der Erzeugung eines neuen Authentifizierungsgeheimnisses nicht zurückzusetzen4.
Den Authentifizierungscode nur einmal verwendbar machen
Der Aufgabentext konzentriert sich auf die Gültigkeitsdauer, doch in der Praxis braucht es zusätzlich:
- Einen erfolgreichen Code sofort ungültig machen
- Die Wiederverwendung desselben Codes ablehnen
- Den Code selbst nicht in Protokollen belassen
- Die Antwort so gestalten, dass sich aus Erfolg oder Misserfolg der Codeprüfung nicht ableiten lässt, ob ein Nutzer existiert
- Auch die Code-Versand-API mit einer Versuchsbegrenzung versehen
Solange ein kurzes Geheimnis verwendet wird, lässt sich die Sicherheit nicht allein der Zufallserzeugung überlassen.
flowchart TB
accTitle: Gegenmaßnahmen für den Authentifizierungscode
accDescr: Über Stellenzahl und Ablaufzeit hinaus mit Versuchsbegrenzung, Wiederverwendungssperre, Benachrichtigung usw. schützen
A[Authentifizierungscode] --> B[Stellenzahl erhöhen]
A --> C[Gültigkeitsdauer verkürzen]
A --> D[Begrenzung der Versuchszahl]
A --> E[Nach Erfolg ungültig machen]
A --> F[Bei Neuversand Fehlerzahl nicht zurücksetzen]
A --> G[Code nicht im Protokoll belassen]
A --> H[Quellbezogene Kontrolle]
Abbildung 11: Gegenmaßnahmen für den Authentifizierungscode. Stellenzahl und Ablaufzeit mit Versuchskontrolle und Betriebspraxis kombinieren.
10. Die vier Punkte aus Teilaufgabe 2 auf einer Seite unterscheiden
Die in Teilaufgabe 2 leicht zu verwechselnden Punkte, geordnet nach dem vom Angreifer kontrollierten Wert.
| Angriff | Vom Angreifer geänderter Wert | Was nicht hätte vertraut werden dürfen | Grundlegende Abhilfe |
|---|---|---|---|
| JWT-Manipulation | alg im JWT-Header, Benutzer-ID in der Payload |
Der vom Token selbst angegebene Prüfalgorithmus | Erlaubte Algorithmen serverseitig festlegen |
| Fremde Informationen abrufen | mid der Anfrage |
Die vom Client angegebene Ziel-ID | Gegen das subject des JWT abgleichen oder die Ziel-ID aus dem JWT bestimmen |
| Wechsel zu zahlendem Nutzer | Nicht spezifiziertes status |
Alle automatisch gebundenen Eigenschaften | Aktualisierbare Eigenschaften als Positivliste führen |
| Durchbruch des 4-stelligen Codes | Kandidaten für otp |
Unbegrenzte Authentifizierungsversuche | Fehlerzahlbegrenzung, Verzögerung, Risikobeurteilung einführen |
Wichtig ist, das nicht alles unter „Eingabewerte validieren“ zusammenzufassen.
algist eine kryptografische Richtliniemidist Autorisierung auf Objektebenestatusist Autorisierung auf Eigenschaftsebeneotpist Widerstandsfähigkeit gegen Online-Raten
Selbst innerhalb derselben HTTP-Anfrage ist der Schutzgrund jeweils ein anderer.
11. Teilaufgabe 3(1) – Externe Codeausführung bestätigen, ohne etwas zu zerstören
Nach dem Start des Diensts wird in der weit verbreiteten Open-Source-Bibliothek H eine kritische Schwachstelle V veröffentlicht. Der Ablauf im Aufgabentext ist folgender.
- Der Angreifer sendet eine Zeichenfolge mit einem JNDI Lookup in einem HTTP-Header
- Der angegriffene Server protokolliert diesen Wert
- Die verwundbare Bibliothek wertet den JNDI Lookup aus und fragt den Angriffs-LDAP-Server ab
- Die LDAP-Antwort liefert die URL des Angriffs-HTTP-Servers
- Der angegriffene Server lädt die Klassendatei und führt den Befehl aus
Mit verschwiegenem Produktnamen liest sich das naheliegend als Angriff vom Typ Log4Shell (CVE-2021-44228). Auch Apaches eigene Beschreibung stellt die Schwachstelle so dar, dass ein Angreifer, der Protokollmeldungen oder Parameter kontrolliert, beliebigen Code ausführen kann, der von einem LDAP-Server geladen wird9.
flowchart LR
accTitle: Bestätigungsablauf für eine Schwachstelle vom Typ Log4Shell
accDescr: Mit einem harmlosen Callback bestätigen, ob die Kette von JNDI bis zur externen Codeausführung tatsächlich durchgeht
A[Angreifer] -->|Injiziert eine jndi/ldap-Nutzlast<br/>in x-api-version| B[Verwundbarer Server]
B --> C[Protokollverarbeitung]
C -->|JNDI Lookup| D[Bösartiger LDAP-Server]
D -->|HTTP-URL-Antwort| E[Bösartiger HTTP-Server<br/>index.html]
E -->|GET aufzeichnen| F[Testserver<br/>Zugriffsprotokoll]
F -->|Erreichbarkeit bestätigt| G[Schwachstelle bestätigt]
Abbildung 12: Bestätigungsablauf für eine Schwachstelle vom Typ Log4Shell. Statt eines destruktiven Befehls wird die Erreichbarkeit durch Aufzeichnung eines HTTP-Zugriffs bestätigt.
Der Prüfcode löst nur einen harmlosen HTTP-Zugriff aus
Unternehmen G führt einen Prüfcode aus, der das System nicht beeinträchtigt, um zu bestätigen, ob sich Schwachstelle V von außen ausnutzen lässt. Der einzige Befehl, den der Prüfcode auslöst, ist das Abrufen der index.html des Testservers.
Teilaufgabe 3(1) fragt, was auf dem Testserver implementiert werden muss, um zu bestätigen, dass der Befehl ausgeführt wurde.
Die Musterlösung lautet:
Ein Mechanismus, der Zugriffe auf die index.html des Testservers aufzeichnet und deren Bestätigung ermöglicht
Verzeichnet das Zugriffsprotokoll des Webservers ein GET vom angegriffenen Server, bestätigt das mindestens, dass die folgende Kette durchgegangen ist.
Externe HTTP-Anfrage
-> Protokollverarbeitung
-> JNDI Lookup
-> LDAP-Antwort
-> Klasse laden
-> Prüfbefehl ausführen
-> HTTP-Zugriff auf den Testserver
Warum „Text auf dem Bildschirm anzeigen“ nicht genügt
Ziel des Angriffs ist der Server. Es ist nicht garantiert, dass sich im Browserbildschirm des Nutzers irgendetwas ändert. Zudem kann die ausgehende Kommunikation auf halbem Weg von einer Firewall gestoppt werden, selbst wenn die Schwachstelle existiert.
Zeichnet der Testserver den Zugriff auf, entsteht ein beobachtbarer Nachweis, dass der angegriffene Server tatsächlich nach außen gelangt ist.
Führen Sie eine solche Prüfung in der Praxis durch, beachten Sie unbedingt Folgendes.
- Holen Sie eine ausdrückliche Genehmigung des Eigentümers des Zielsystems ein
- Wählen Sie eine Prüfmethode ohne oder mit vertretbar geringer Auswirkung auf den Produktivbetrieb
- Verwenden Sie keine destruktiven Befehle wie Schreiben, Löschen oder Konfigurationsänderungen
- Verwalten Sie Prüfdomäne und -server selbst
- Zeichnen Sie Prüfzeitpunkt, Quelle, Ziel und erwarteten Callback auf
- Entfernen Sie temporäre LDAP- oder HTTP-Server sowie Zugangsdaten nach der Prüfung
„Bestätigen, dass beliebige Codeausführung möglich ist“ und „beliebigen gefährlichen Code ausführen“ sind nicht dasselbe. Beschränken Sie die Nebenwirkungen auf das für das Ziel nötige Minimum.
12. Teilaufgabe 3(2)(3) – Die WAF prüft den HTTP-Header
Die WAF von Dienst N lässt als Prüfziel GET, POST, PUT, ANY, Header, COOKIE oder Multipart zu.
Der Angriffscode steckt im Wert eines HTTP-Headers namens x-api-version. Die Lücken e und f in Tabelle 6 lauten daher beide Header.
Den im Text genannten Ort direkt auf das WAF-Prüfziel abbilden
Hier geht es weniger um allgemeines Wissen als darum, den Datenfluss im Aufgabentext zu lesen.
Ort der Angriffszeichenfolge:
x-api-version-Header
|
v
Prüfziel der WAF:
Header
Es ist weder ein GET-Parameter noch ein POST-Body. Statt aus der Funktionsliste der WAF „klingt nach Angriff, also ANY“ zu wählen, antworten Sie mit dem Ort, an dem der Aufgabentext den Angreifer den Wert platzieren lässt.
Groß-/Kleinschreibung berücksichtigen
Der erste Vorschlag folgte konzeptionell dieser Regel.
Header \Wjndi\W sperren
Header \Wldap\W sperren
Vertauscht man aber, wie bei jNdI, Groß- und Kleinschreibung, lässt sich ein einfaches, nur auf Kleinbuchstaben passendes Muster umgehen.
Die Musterlösung zu Teilaufgabe 3(3) ist einer der beiden folgenden Ausdrücke.
\W[jJ][nN][dD][iI]\W
\W(j|J)(n|N)(d|D)(i|I)\W
Im Aufgabenheft kann der Backslash in der japanischen Schriftform wie ein Yen-Zeichen aussehen, als regulärer Ausdruck ist es aber \W. \W passt auf jedes Zeichen außer Buchstaben, Ziffern und Unterstrich. In der Syntax von JNDI Lookup stehen unmittelbar vor und nach jndi Nicht-Wort-Zeichen wie ${ oder :, und das Muster ist so geschrieben, dass es diese mit erfasst.
Nach demselben Prinzip lässt sich auch die ldap-Seite groß-/kleinschreibungsunabhängig machen.
\W[lL][dD][aA][pP]\W
Diesen regulären Ausdruck nicht für eine „vollständige Log4Shell-Abwehr“ halten
Die Prüfung verlangt einen regulären Ausdruck, der die im Aufgabentext gezeigte Umgehungsmethode abdeckt. In echten Angriffen sind Aufteilung von Zeichenketten, andere Lookup-Varianten, Kodierung, andere Protokolle und weitere Abwandlungen möglich, die sich mit Signaturen allein schwer vollständig abdecken lassen.
Die praktische Einordnung ist daher folgende.
- Bereits bekannte Angriffsmuster vorläufig per WAF stoppen
- Untersuchen, ob die betroffene Bibliothek tatsächlich enthalten ist
- Ausgehendes LDAP, RMI und unnötigen HTTP-Verkehr einschränken
- Auf eine korrigierte Version aktualisieren
- Auch nach dem Update die Protokolle prüfen und auf einen möglichen Einbruch untersuchen
Die WAF ist eine Schicht, die Zeit erkauft, bis eine korrigierte Version verfügbar ist.
flowchart TB
accTitle: Einordnung der WAF
accDescr: Die WAF ist eine vorläufige Abwehrschicht, die grundlegende Abhilfe ist die Aktualisierung der Bibliothek auf eine korrigierte Version
A[Kritische Schwachstelle veröffentlicht] --> B[Auswirkung bestätigen]
B --> C[Vorläufige Abwehr]
C -->|WAF-Regel<br/>Erkennung/Sperrung| D[Angriffsmuster vorübergehend stoppen]
C -->|Ausgehenden Verkehr einschränken| E[Missbrauchsweg schließen]
D --> F[Auf korrigierte Bibliothek aktualisieren]
E --> F
F --> G[Nachträgliche Prüfung und Vorbeugung]
Abbildung 13: Einordnung der WAF. Die WAF erkauft nur Zeit bis zum Patch; die grundlegende Abhilfe ist das Update.
13. Teilaufgabe 3(4) – Warum zuerst „Erkennung“ verwenden
Zur geänderten WAF-Regel rät Z, ein Registered Security Specialist, den Modus für einen bestimmten Zeitraum nach dem Produktivstart nicht auf „Sperrung“, sondern auf „Erkennung“ zu stellen.
Die Teilaufgabe fragt, jeweils in ≤25 Zeichen, nach dem Vorteil des Erkennungsmodus und danach, was zur Schadensminimierung zu tun ist.
Die Musterlösung lautet:
| Punkt | Kern der Antwort |
|---|---|
| Vorteil | Kann eine Sperrung durch Fehlalarme verhindern |
| Durchzuführende Maßnahme | Bei Eingang eines Alarms prüfen, ob es sich um einen Angriff handelt |
Der Erkennungsmodus ist kein „Nichts-tun“-Modus
Im Erkennungsmodus wird Datenverkehr, der auf eine Regel passt, weiterhin durchgelassen, aber protokolliert und mit einem Alarm versehen. Taucht in einem normalen API-Aufruf zufällig die Zeichenfolge jndi oder ldap auf, wird der Geschäftsbetrieb dadurch nicht sofort gestoppt.
Im Gegenzug braucht es auf der Betriebsseite Folgendes.
Alarm eingegangen
|
v
Betroffene Anfrage prüfen
|
+-- Normaler Verkehr -> Regel einschränken, Ausnahme erwägen
|
+-- Angriff -> Ziel isolieren, Protokolle sichern, Auswirkung untersuchen, zu Sperrung wechseln
Sieht sich niemand die Alarme an, hat der Erkennungsmodus überhaupt keine Schutzwirkung. Erkennung wirkt nur zusammen mit einem Betrieb, der beobachtet und beurteilt.
Der Weg von Erkennung zu Sperrung
Ein typisches Einführungsverfahren sieht so aus.
- Erkennungsmodus auf echten Datenverkehr anwenden
- Fehlalarme von echten Treffern unterscheiden
- Betroffenen Header, Pfad, API, Wortgrenzen usw. abstimmen
- Bestätigen, dass die Auswirkung auf normalen Verkehr vertretbar ist
- In den Sperrmodus wechseln
- Anzahl der Sperrungen und geschäftliche Auswirkung überwachen
Das ist allerdings das Prinzip für den Normalfall. Ist eine Schwachstelle kritisch, wird sie bereits aktiv ausgenutzt und gibt es keine Alternative, kann der Schaden durch einen Einbruch höher eingeschätzt werden als der durch einen Fehlalarm verursachte Ausfall, sodass von Anfang an gesperrt wird. Im Szenario der Prüfung wird zunächst die Erkennung gewählt, um zu bestätigen, dass sich der Dienst wie bisher weiter nutzen lässt.
flowchart LR
accTitle: Von der WAF-Erkennung zur Sperrung
accDescr: Alarme im Erkennungsmodus beobachten, Fehlalarme abstimmen, dann in den Sperrmodus wechseln
A[Erkennungsmodus] -->|Echter Verkehr| B[Alarm ausgelöst]
B --> C{Angriff oder<br/>Fehlalarm}
C -->|Fehlalarm| D[Regel anpassen]
D --> A
C -->|Angriff| E[In den Sperrmodus wechseln]
E --> F[Anzahl Sperrungen und geschäftliche Auswirkung überwachen]
Abbildung 14: Von der Erkennung zur Sperrung. Erst beobachten und abstimmen, dann die Auswirkung als vertretbar bestätigen und zur Sperrung wechseln.
14. Die WAF ist eine vorläufige Maßnahme, das Update die grundlegende Abhilfe
Im Aufgabentext hatte die offizielle Website der Bibliothek H weder eine korrigierte Version noch eine vorläufige Abhilfe, und selbst die umfassende WAF-Regel des Cloud-Anbieters sollte bis zu 72 Stunden dauern. Also bestätigt Unternehmen G die Auswirkung selbst und blockiert vorläufig zumindest die bereits bekannten Muster.
Diese Reihenfolge ist die Grundform der Vorfallsreaktion.
| Phase | Zweck | Umsetzung in dieser Aufgabe |
|---|---|---|
| Auswirkung bestätigen | Beurteilen, ob das eigene Unternehmen tatsächlich gefährdet ist | Ausnutzbarkeit von außen mit einem harmlosen Callback bestätigen |
| Vorläufige Abwehr | Zeit bis zur Korrektur erkaufen | WAF-Regeln, Erkennung/Sperrung, Einschränkung ausgehenden Verkehrs |
| Grundlegende Korrektur | Die verwundbare Ursache beseitigen | Auf eine korrigierte Bibliothek aktualisieren |
| Nachträgliche Prüfung | Untersuchen, ob bereits ausgenutzt wurde | Protokolle von WAF, Anwendung, DNS, Proxy usw. untersuchen |
| Vorbeugung | Die nächste Entscheidung beschleunigen | Bestandsaufnahme der Abhängigkeiten, SBOM, Aktualisierungsverfahren, Kontaktweg |
„Wir wissen nicht, ob wir es benutzen“ ist die größte Ursache für Verzögerung
Im Aufgabentext dauert es, selbst als Unternehmen G bei Unternehmen F anfragt, ob Bibliothek H genutzt wird, wegen einer nötigen detaillierten Konfigurationsanalyse.
In der Praxis kommt es zu Verzögerungen, wenn man erst nach der Veröffentlichung einer kritischen Schwachstelle anfängt, JAR-Dateien zu suchen. Mindestens Folgendes sollte schon im Normalbetrieb vorhanden sein.
- Eine Liste direkter und transitiver Abhängigkeiten
- Die tatsächlich in den Auslieferungsartefakten enthaltenen Komponenten und Versionen
- An welche Dienste, Container und Endgeräte diese verteilt sind
- Ein Verfahren, um eine abhängige Bibliothek zu aktualisieren und neu zu bauen bzw. auszuliefern
- Einen Kontaktweg zur Genehmigung von Notfalländerungen
- Erlaubte Ziele für ausgehenden Verkehr und die Auswirkung, sie zu sperren
- Speicherort der Protokolle und wie man darin sucht
Ein SBOM ist nicht das Ziel an sich. Es ist ein Index, um in kurzer Zeit zu beantworten: „Welche laufenden Systeme betrifft diese Schwachstelle?“
Nach dem Update die Untersuchung nicht beenden
Möglicherweise wurde bereits vor oder nach Veröffentlichung der Schwachstelle angegriffen. Ein Update auf die korrigierte Version stoppt künftigen Missbrauch, beseitigt aber weder bereits kompromittierte Zugangsdaten noch eine bereits eingerichtete Hintertür.
Bei einer Schwachstelle vom Typ Log4Shell untersuchen Sie mindestens die folgenden Aspekte.
- HTTP-Anfragen mit verdächtigen Zeichenfolgen, die auf JNDI oder LDAP hindeuten
- Kommunikation vom Anwendungsserver nach außen zu LDAP, RMI oder HTTP
- Ungewöhnlich gestartete Kindprozesse
- Erstellung verdächtiger JAR-, Class-, Skript- oder ausführbarer Dateien
- Zugriffe auf Cloud-Zugangsdaten oder Umgebungsvariablen
- Authentifizierung, Berechtigungsänderungen und ausgehende Übertragungen rund um den Update-Zeitpunkt
Wichtig ist, allein aus WAF-Protokollen nicht auf „kein Angriff“ zu schließen. Es gibt interne Wege, die nie durch die WAF laufen, und Protokolle, die in der Vergangenheit nicht aufbewahrt wurden.
15. Eine Lesart, mit der sich in der Prüfung leichter punkten lässt
Diese Aufgabe ist weniger eine Wissensfrage als eine Übung darin, die Lücke zwischen Spezifikation und Implementierung zu lesen.
15.1 „Spezifikation“ und „Implementierung“ in den Tabellen trennen
Beim status-Problem geht ein Wert, der in der API-Spezifikation fehlt, in der Implementierung trotzdem durch.
Spezifikation:
mid / name / age
Implementierung:
alle empfangenen Parameter an P senden
Ist diese Lücke sichtbar, wird klar, dass Lücke c das gemeinsame Modul P ist.
15.2 Eine Linie unter den vom Angreifer geänderten Wert ziehen
Der bei jedem Angriff geänderte Wert ist:
algim JWT-Header- Benutzer-ID in der JWT-Payload
- API-Parameter
mid - Nicht spezifiziertes
status otpder Authentifizierungs-API- HTTP-Header
x-api-version
Fast jede Teilaufgabe fragt, „wo dieser Wert geprüft werden sollte“.
15.3 Die Antwort auf die Begriffe des Aufgabentexts zurückführen
In der Praxis lässt sich das „BOLA“, „Mass Assignment“ und „Rate Limiting“ nennen. Doch gefragt ist eine konkrete, an den Aufbau des Aufgabentexts angepasste Verarbeitung.
Schlechtes Beispiel:
Autorisierung angemessen durchführen.
Gutes Beispiel:
Prüfen, ob die im JWT enthaltene Benutzer-ID mit dem Wert von mid übereinstimmt.
Schlechtes Beispiel:
Brute-Force-Gegenmaßnahmen treffen.
Gutes Beispiel:
Das Konto sperren, sobald die Anzahl aufeinanderfolgender Fehlversuche den Schwellenwert überschreitet.
Allein den abstrakten Namen zu kennen, ergibt noch keine im Zeichenlimit bewertbare Antwort.
15.4 Bei der WAF verfolgen, „wo es hineingelangt ist“
Das Prüfziel der WAF bestimmt sich nicht durch Raten anhand der Angriffsart, sondern anhand des Orts, an dem die Angriffszeichenfolge platziert wurde.
In den x-api-version-Header gelegt
↓
Prüfziel ist Header
Dass die Erfolgsquote bei Teilaufgabe 3(1) laut Auswertungskommentar etwas geringer war, lag auch daran, dass viele Antworten nicht zum Angriffsablauf aus Abbildung 6 passten. Schon das bloße Nachzeichnen des Angriffsablaufs mit Pfeilen zeigt, was beobachtet werden sollte.
16. Eine Checkliste für praktische API-Reviews
Eine Checkliste, um diese Aufgabe in konkrete Design- und Code-Reviews zu übertragen.
JWT-Prüfung
- Der erlaubte Signaturalgorithmus ist in der Serverkonfiguration festgelegt
noneund unerwartete Algorithmen werden abgelehnt- Signatur,
iss,aud,expundnbfwerden je nach Verwendungszweck geprüft - ID-Token, Access-Token und Refresh-Token werden nicht verwechselt
- Es gibt ein Verfahren für Schlüsselrotation und Widerruf
- Geheim zu haltende Informationen stehen nicht in der JWT-Payload
Autorisierung auf Objektebene
- Ändert man die ID in einer Anfrage, lassen sich fremde Daten nicht erreichen
- Autorisierung erfolgt bei Liste, Detail, Aktualisierung, Löschung und Download gleichermaßen
- Autorisierung erfolgt in einer gemeinsamen Schicht, die die Daten erreicht, nicht im Bildschirm
- Bei rein eigenen APIs wurde erwogen, die Ziel-ID aus dem Token abzuleiten
- Administratoroperationen nutzen eine andere Richtlinie als die allgemeine Nutzer-API
Autorisierung auf Eigenschaftsebene
- Externer Eingabetyp und Datenbankentität sind getrennt
- Aktualisierbare Felder sind als Positivliste aufgeführt
- Nicht spezifizierte Eigenschaften werden abgelehnt oder protokolliert
- Zustände wie Berechtigung, Abrechnung, Genehmigung oder Eigentümerschaft lassen sich nicht über Nutzereingaben ändern
- Auch Antworten enthalten keine unnötigen vertraulichen Eigenschaften
Authentifizierungsversuche
- Es gibt eine kontobezogene Begrenzung der Fehlerzahl
- Es gibt gestaffelte Verzögerung und quellbezogene Kontrolle
- Die Fehlerzahl wird bei einer erneuten Codeausstellung nicht zurückgesetzt
- Der Authentifizierungscode ist nur einmal verwendbar
- Authentifizierungscodes und Passwörter werden nicht protokolliert
- Entsperrung/Wiederherstellung ist kein separater, schwächerer Authentifizierungsweg
Kritische Schwachstellen in abhängigen Bibliotheken
- Laufende Dienste lassen sich ihren Abhängigkeitsversionen zuordnen
- Es gibt ein Verfahren, die Auswirkung auf harmlose Weise zu prüfen
- Vorläufige Maßnahmen wie WAF-Regeln und Einschränkung ausgehenden Verkehrs lassen sich anwenden
- Es gibt einen Betriebsprozess, in dem eine zuständige Person Erkennungsalarme prüft
- Es gibt einen Notfall-Release-Weg für die Aktualisierung auf eine korrigierte Version
- Vor dem Update wird in den Protokollen nach möglichem Missbrauch gesucht
17. Die zwei Gesichter gemeinsamer Bausteine, wie diese Aufgabe sie zeigt
In dieser Aufgabe treten zwei gemeinsame Bausteine auf: die JWT-Verwaltungsbibliothek Q und das gemeinsame Modul P.
Gemeinsame Bausteine bringen große Vorteile.
- Eine Korrektur an einer Stelle wirkt auf alle nutzenden APIs
- Autorisierungs- und Prüflogik muss nicht in jeder Funktion dupliziert werden
- Testziele lassen sich bündeln
- Protokoll- und Audit-Formate lassen sich vereinheitlichen
Andererseits breiten sich auch Fehler auf das Ganze aus.
- Akzeptiert Bibliothek Q
alg=none, wird jede JWT nutzende API gefährdet - Akzeptiert das gemeinsame Modul P eine beliebige
midoder ein beliebigesstatus, werden sowohl GET als auch PUT gefährdet - Wird die verwundbare Bibliothek H im Fundament genutzt, wird jeder Weg, der HTTP-Header protokolliert, Teil der Angriffsfläche
Zu vereinheitlichen ist deshalb nicht bloß der Datenzugriff. Nötig ist, die Sicherheitsinvarianten selbst zu vereinheitlichen und diesen gemeinsamen Baustein isoliert streng zu prüfen.
Gestalten Sie zum Beispiel den Vertrag von P so.
P.getOwnUser(authenticatedSubject)
P.updateOwnProfile(authenticatedSubject, ProfileUpdate{name, age})
Eine niedrigschwellige API wie die folgende sollte gewöhnlichen Aufrufern besser nicht direkt offenstehen.
P.getUser(arbitraryMid)
P.updateUser(arbitraryMap)
Letztere wird nur an wenigen, begrenzten Stellen benötigt, etwa in der Verwaltung. Gibt man diese niedrigschwellige Freiheit an alle APIs weiter, entsteht ein Entwurf, der darauf angewiesen ist, dass jeder Aufrufer sie jedes Mal korrekt verwendet.
18. Zusammenfassung
Aufgabe 1 der Nachmittagsprüfung Frühjahr 2024 (Reiwa 6) liest die Themen der API-Sicherheit einzeln auseinander.
Ein JWT zu verwenden bedeutet nicht, dass die Authentifizierung sicher ist. Lässt man den Angreifer den Signaturalgorithmus wählen, lässt sich die Benutzer-ID umschreiben.
Eine gültige JWT-Signatur bedeutet nicht, dass die Autorisierung korrekt ist. Vertraut man der mid der Anfrage, kann ein rechtmäßiger Nutzer auf die Informationen eines anderen zugreifen.
Das eigene Objekt aktualisieren zu können bedeutet nicht, dass jede Eigenschaft geändert werden darf. Wird ein interner Zustand wie status automatisch gebunden, lassen sich Berechtigungen oder Zahlungsstatus umschreiben.
Dass der Authentifizierungscode eine Gültigkeitsdauer hat, bedeutet nicht, dass er gegen Brute-Force resistent ist. Kandidatenraum und Versuchsgeschwindigkeit müssen berechnet und die Fehlerzahl begrenzt werden.
Eine Regel in die WAF einzutragen bedeutet nicht, dass die Schwachstelle behoben ist. Erkennung und Sperrung erkaufen nur Zeit; die Auswirkung wird geprüft und die Bibliothek letztlich aktualisiert.
flowchart TB
accTitle: Zuordnung von Schwachstellen zu Gegenmaßnahmen
accDescr: Ordnet jede Schwachstelle ihrer Vertrauensgrenze und ihrer Gegenmaßnahme zu
A[JWT-Manipulation] -->|Tokenprüfung| B[Erlaubten Algorithmus festlegen]
C[mid-Austausch] -->|Autorisierung auf Objektebene| D[Gegen JWT-subject abgleichen/mid unnötig]
E[status=paid] -->|Autorisierung auf Eigenschaftsebene| F[Aktualisierungs-DTO als Positivliste]
G[Brute-Force des 4-stelligen Codes] -->|Kontrolle der Authentifizierungsversuche| H[Fehlerzahlbegrenzung/Verzögerung]
I[Schwachstelle vom Typ Log4Shell] -->|Von Eingabe zu Ausführung| J[Bibliotheksupdate/WAF]
Abbildung 15: Zuordnung von Schwachstellen zu Gegenmaßnahmen. Die Abhilfe je nach gebrochener Grenze trennen.
Ein Prinzip zieht sich durch diese gesamte Aufgabe.
Den Erfolg der vorherigen Prüfung niemals zum Grund machen, die nächste Vertrauensgrenze zu überspringen.
Frühere Artikel dieser Serie behandeln den gespeicherten XSS-Angriff aus Aufgabe 1 der Nachmittagsprüfung Herbst 2023 (Reiwa 5) und das Hinausbringen von Daten über das Gäste-WLAN aus Aufgabe 2 der Nachmittagsprüfung Herbst 2023 (Reiwa 5). Für einen Blick auf die Prüfpunkte einer Website als Ganzes siehe auch IPAs „Anleitung zum sicheren Website-Bau“ als Checkliste nutzen.
flowchart TB
accTitle: Abschließende Zusammenfassung
accDescr: Zeigt, dass der Erfolg der vorherigen Prüfung nie ein Grund ist, die nächste Vertrauensgrenze zu überspringen
A[Authentifizierung erfolgreich] --> B[JWT-Signaturprüfung]
B --> C[Autorisierung auf Objektebene]
C --> D[Autorisierung auf Eigenschaftsebene]
D --> E[Begrenzung der Versuchszahl]
E --> F[Grenze von Eingabe zu Ausführung]
F --> G[WAF/Bibliotheksupdate]
Abbildung 16: Abschließende Zusammenfassung. Vertrauensgrenzen werden stufenweise geprüft, keine darf übersprungen werden.
Quellen
-
IPA, Prüfung zum Registered Information Security Specialist, Frühjahr 2024 (Reiwa 6), Nachmittags-Aufgabenheft. Der Aufgabentext, auf dem dieser Artikel beruht. ↩
-
IPA, Prüfung zum Registered Information Security Specialist, Frühjahr 2024 (Reiwa 6), Nachmittags-Musterlösungen. Die offizielle Musterlösung zu jeder Teilaufgabe. ↩
-
IPA, Prüfung zum Registered Information Security Specialist, Frühjahr 2024 (Reiwa 6), Nachmittags-Auswertungskommentar. Eine Erklärung der Erfolgsquoten und typischen Fehler. ↩
-
NIST, SP 800-63B: Authentication and Authenticator Management. Legt unter anderem Stellenzahlen für kurzfristige Geheimnisse, Begrenzungen der Versuchszahl, die Fehlerzahl bei Neuausstellung und den Verzicht auf E-Mail für die Out-of-Band-Authentifizierung fest. ↩ ↩2
-
RFC Editor, RFC 7519: JSON Web Token (JWT). Die Spezifikation von JWTs einschließlich des Unsecured JWT und
alg=none. ↩ -
RFC Editor, RFC 8725: JSON Web Token Best Current Practices. Das BCP-Dokument, das unter anderem das Festlegen erlaubter Algorithmen sowie die Prüfung von Aussteller, Subjekt und Audience beschreibt. ↩
-
OWASP, API1:2023 Broken Object Level Authorization. Erklärt die Notwendigkeit, die Autorisierung für jede vom Nutzer angegebene Objekt-ID zu prüfen. ↩
-
OWASP, API3:2023 Broken Object Property Level Authorization. Erklärt Autorisierungslücken auf Eigenschaftsebene einschließlich Mass Assignment sowie Gegenmaßnahmen. ↩
-
Apache Logging Services, Security. Erklärt die Auswirkung von CVE-2021-44228, die Codeausführung über JNDI und LDAP sowie die korrigierten Versionen. ↩
Verwandte Artikel
Aktuelle Artikel mit denselben Schlagwörtern führen zu verwandten Themen weiter.
Prüfung zum Registered Information Security Specialist – Herbst 2023 (Reiwa 5), Nachmittag, Aufgabe 1 erklärt – Das Stored XSS, bei dem von 16 Bewertungen nur 2 angezeigt werden
Anhand von Aufgabe 1 der Nachmittagsprüfung Herbst 2023 (Reiwa 5) zum Registered Information Security Specialist erklärt dieser Artikel d...
Prüfung zum Registered Information Security Specialist – Herbst 2023 (Reiwa 5), Nachmittag, Aufgabe 2 erklärt – Dateien, die über das Gäste-WLAN entwendet werden
Anhand von Aufgabe 2 der Nachmittagsprüfung Herbst 2023 (Reiwa 5) zum Registered Information Security Specialist erklärt dieser Artikel, ...
Was auch Website-Auftraggeber wissen sollten ── Die IPA-Anleitung „So sichern Sie Ihre Website“ als Checkliste nutzen
An welchem Maßstab sollten Sie die Sicherheit der Website Ihres Unternehmens prüfen? Dieser Artikel erklärt die 11 Schwachstellen und Geg...
Die 10 größten Bedrohungen der Informationssicherheit 2026 — Wie man das Ranking liest und was KMU wirklich absichern sollten
In IPAs „10 größte Bedrohungen der Informationssicherheit 2026“ belegten Ransomware-Angriffe zum 11. Mal in Folge Platz 1, Supply-Chain-A...
Wo sollten KMU bei der Sicherheit anfangen? — Ein Durchgang durch die IPA-„Informationssicherheitsleitlinien für KMU“, 4. Ausgabe
Wo sollten kleine und mittlere Unternehmen bei der Sicherheit anfangen? Anhand der IPA-„Informationssicherheitsleitlinien für kleine und ...
Verwandte Themen
Diese Seiten ordnen den Artikel in einen größeren Leistungs- und Entscheidungskontext ein.
Technische Windows-Themen
Portal zu Windows-Entwicklung, Fehleranalyse und der Nutzung bestehender Assets.
Leistungen zu diesem Thema
Dieser Artikel ist direkt mit den folgenden Leistungen verbunden.
Website-Entwicklung
Bei Mitglieder-APIs und der Anbindung von Smartphone-Apps wirken sich JWT-Prüfung, Autorisierung auf Objektebene und die Beschränkung aktualisierbarer Eigenschaften unmittelbar auf die Sicherheit des Websystems aus.
Technische Beratung und Design-Review
Weil es zum Bereich der Technikberatung gehört, Autorisierungslücken in bestehenden APIs, die Auswirkungsreichweite abhängiger Bibliotheken und vorläufige WAF-Regeln im Rahmen eines Design-Reviews aufzudecken.
Häufige Fragen
Fragen, die in Beratungen zu diesem Artikelthema häufig gestellt werden.
- Warum lässt sich jemand anderes vortäuschen, obwohl die JWT-Signaturprüfung erfolgreich war?
- In dieser Aufgabe akzeptierte die JWT-Verwaltungsbibliothek das alg im JWT-Header genau so, wie der Angreifer es vorgab, und behandelte ein JWT mit alg=none als gültig – ohne Signatur. Deshalb gelingt die Prüfung auch dann, wenn die Benutzer-ID in der Payload umgeschrieben wird. Die Prüfungsantwort lautet, als zu prüfenden Wert das alg im JWT-Header heranzuziehen und zu bestätigen, dass sein Wert nicht NONE ist. In der Praxis reicht es allerdings nicht, nur NONE abzulehnen. Legen Sie in der serverseitigen Konfiguration die erlaubten Algorithmen fest, etwa auf RS256, und verwenden Sie den vom Token selbst angegebenen Algorithmus nie unmittelbar für die Auswahl. Prüfen Sie außerdem je nach Verwendungszweck issuer, audience, Gültigkeitsdauer und subject.
- Reicht es als Autorisierungsmaßnahme, die Benutzer-ID im JWT mit der mid der Anfrage zu vergleichen?
- Für die Zwecke dieser Prüfungsantwort ist das ausreichend. Prüft das gemeinsame Modul P, ob die im JWT enthaltene Benutzer-ID mit mid übereinstimmt, lässt sich ein Angriff stoppen, der eine fremde mid angibt. Bei einer API, die aber nur die eigenen Informationen des Aufrufenden behandelt, ist es in der Praxis sicherer, mid gar nicht erst vom Client entgegenzunehmen und die Benutzer-ID stattdessen aus dem subject des geprüften JWT zu bestimmen. Mit Endpunkten wie GET /users/me oder PUT /users/me lässt sich vermeiden, dass die Vergleichsprüfung überhaupt vergessen werden kann. Eine API, über die ein Administrator andere Nutzer bearbeitet, gehört auf einen eigenen Endpunkt mit eigener Autorisierungsrichtlinie.
- Warum lässt sich der Angriff, der status hinzufügt, nicht allein durch gewöhnliche Eingabevalidierung verhindern?
- Weil es nichts nützt, die Länge von name oder den Wertebereich von age zu prüfen, wenn status – ein Feld, das gar nicht erst angenommen werden sollte – ohnehin automatisch gebunden und an das interne Objekt weitergereicht wird. Das Problem ist nicht das Format eines Werts, sondern die Autorisierung auf Eigenschaftsebene: ob der Nutzer diese Eigenschaft überhaupt ändern darf. Definieren Sie im Eingabetyp für Aktualisierungen ausschließlich name und age, und lehnen Sie unbekannte Eigenschaften ab. Der Zahlungsstatus darf nur durch serverseitig vertrauenswürdige Ereignisse geändert werden, etwa das Erfolgsergebnis des Zahlungsdiensts.
- Der vierstellige Authentifizierungscode verfällt nach 10 Minuten – warum ist das trotzdem gefährlich?
- Weil es von 0000 bis 9999 nur 10.000 mögliche Werte gibt und bei 10 Versuchen pro Sekunde im Durchschnitt nach 5.000 Versuchen, also 500 Sekunden, der Treffer gelingt. Die Gültigkeitsdauer von 10 Minuten entspricht 600 Sekunden – probiert man sich also der Reihe nach ohne Wiederholung durch, lassen sich innerhalb der Gültigkeitsdauer 6.000 Kombinationen prüfen. Die Ablaufzeit allein stoppt ein Brute-Force nicht. Kandidatenzahl, Versuchsgeschwindigkeit und Obergrenze der Versuche müssen gemeinsam entworfen werden.
- Die Prüfungsantwort ist eine Kontosperre – reicht in der Praxis auch eine sofortige Sperre allein?
- Nein. In die Lücke der Aufgabe gehört zwar eine Verarbeitung, die das Konto sperrt, sobald die Anzahl aufeinanderfolgender Fehlversuche einen Schwellenwert überschreitet, doch eine feste, dauerhafte Sperre allein erlaubt einem Angreifer, absichtlich das Konto einer anderen Person zu sperren und so einen Denial-of-Service auszulösen. In der Praxis kombiniert man eine kontobezogene Fehlerzahl, gestaffelte Wartezeiten, eine Risikobewertung nach Quelle oder Gerät, Benachrichtigungen und ein Wiederherstellungsverfahren. Wichtig ist auch, dass die Fehlerzahl beim Ausstellen eines neuen Codes nicht auf null zurückgesetzt wird.
- Was bringt es, die WAF auf Erkennung statt auf Sperrung zu stellen?
- Dass geschäftlicher Datenverkehr auch dann nicht gestoppt wird, wenn eine normale Zeichenfolge fälschlich als Angriff eingestuft wird. Die Musterlösung nennt als Vorteil, dass sich eine Sperrung durch Fehlalarme vermeiden lässt, und als durchzuführende Maßnahme, bei Eingang eines Alarms zu prüfen, ob es sich um einen Angriff handelt. Der Erkennungsmodus ist keine Einstellung zum Sich-selbst-Überlassen. Er dient als Beobachtungszeitraum, in dem Sie Protokolle prüfen, Fehlalarme aussortieren, die Regel anpassen und dann zur Sperrung übergehen. In einem Notfall, in dem eine bekannte, kritische Schwachstelle bereits aktiv ausgenutzt wird, kann es angemessen sein, das Verfügbarkeitsrisiko gegen den Schaden abzuwägen und von Anfang an zu sperren.
- Ist die Bibliothek H in dieser Aufgabe Log4j?
- Der Aufgabentext verschweigt zwar den Produktnamen, doch der Ablauf des Angriffs – JNDI Lookup, ein LDAP-Server, das Nachladen einer Klasse von einem HTTP-Server, eine in einen HTTP-Header eingebettete Zeichenfolge und ein hoher CVSS-v3.1-Basiswert – lässt sich naheliegend als Abstraktion von CVE-2021-44228 lesen, bekannt als Log4Shell. Dieser Artikel erklärt diese Entsprechung, doch in der Prüfung muss der konkrete Produktname nicht genannt werden. Sie lässt sich allein aus dem vorgegebenen Angriffsablauf und der WAF-Spezifikation beantworten.
- Was sollte man aus dieser Aufgabe für die eigene Praxis mitnehmen?
- Dass eine erfolgreiche Authentifizierung, ein unverändertes JWT, der erlaubte Zugriff auf das Zielobjekt und die erlaubte Änderung der Zieleigenschaft allesamt getrennte Prüfungen sind. Hinzu kommt, dass ein kurzer Authentifizierungscode eine Begrenzung der Versuchszahl braucht und dass bei einer schwerwiegenden Bibliotheksschwachstelle Wirkungsprüfung, vorläufige Verteidigung und grundlegende Korrektur parallel vorangetrieben werden. Im Kern der Praxis stehen: Autorisierung in gemeinsamen Bausteinen bündeln, das Eingabeschema als Positivliste gestalten, die Prüfbedingungen des JWT serverseitig festlegen und abhängige Bibliotheken im Blick behalten, damit sie aktualisiert werden können.
Autorenprofil
Profilseite des Artikelautors.
Go Komura
Geschäftsführer von KomuraSoft LLC
Spezialisiert auf Windows-Softwareentwicklung, technische Beratung und Fehleranalyse, insbesondere bei bestehenden Systemen und schwer reproduzierbaren Störungen.