JWT-Schwachstellen: None-Algorithmus und Key-Confusion
Im folgenden Beitrag geht es um JSON Webtokens und worauf bei dem Einsatz von Ihnen geachtet werden muss. Dazu werden in diesem Beitrag die zwei einfachsten Angriffe erklärt und darüber aufgeklärt wie diese zu verhindern sind. JSON Webtokens werden für die Authentifizierung von Nutzern verwendet. Somit ist das Ziel des Angreifers ein JSON Webtoken zu manipulieren und es vom Server als gültiges Webtoken verifizieren zu lassen.
Was sind JSON Webtokens (JWT)?
JSON Webtokens sind im RFC 7519 definiert und bestehen aus drei Bausteinen: dem JOSE Header, JWS Payload und der kodierten Signatur. Im JOSE Header können unter anderem folgende Parameter gesetzt werden: alg, jwk, kid, x5u, x5c, x5t, typ, cty und crit. Dabei sind alle Parameter bis auf der „alg“ Parameter optional, d.h. diese müssen nicht implementiert sein. Der alg Parameter beschreibt den Algorithmus welcher z.B. für das Erstellen der digitalen Signatur benutzt wurde. Die Parameter jwk, kid, x5u, x5c und x5t werden für die Schlüsselidentifizierung verwendet. Im Headerparameter typ kann der Typ des JSON festgelegt werden (z.B. typ=JWT für einen JSON Webtoken). Der Content Type des Payloads wird mit dem Parameter cty beschrieben und der Parameter crit legt fest, dass alle Ergänzten Parameter verstanden werden müssen. In folgender Grafik ist ein beispielhafter JSON Web Token dargestellt. Die einzelnen Elemente des JSON Webtokens werden Base64 kodiert und mit einem Punkt getrennt. Die Signatur wird über den Header und Payload gebildet.
Nutzung von JSON Webtokens in einem Beispiel
JSON Webtokens werden in unterschiedlichen Bereichen verwendet. Unter anderem bei Diensten wie 0Auth oder OpenIDConnect. Es soll sich folgendes Szenario vorgestellt werden. Es gibt einen Server und einen Nutzer, der sich mithilfe seines JSON Webtokens authentifizieren möchte. Dazu sendet der Nutzer dem Server seinen JSON Webtoken zu und der Server soll diesen nun verifizieren. Dazu dekodiert der Server die einzelnen Teile des JSON Webtokens (Header, Payload und Signatur). Da es sich bei HS256 um ein symmetrisches Signaturverfahren handelt, besitzen Server und Nutzer einen gemeinsamen Schlüssel. Somit bildet der Server eine Signatur über den erhaltenen Header und dem Payload und vergleicht diesen mit der Signatur aus dem JSON Webtoken. Wenn die beiden Signaturen gleich sind, handelt es sich um ein gültigen JSON Webtoken. Dieses Verfahren kann in der folgenden Abbildung betrachtet werden.
Mögliche Angriffsvektoren
Ziel des Angreifers ist es ein JWT zu erzeugen, welches von dem Server akzeptiert wird. Eine Möglichkeit genau das zu erreichen, ist den Parameter „alg“ auf „none“ zu setzen. Der Wert „none“ bedeutet, dass das JWT nicht signiert ist bzw. dass der „none“ Algorithmus zum Signieren dieses JWT benutzt wurde (genauso ist es in RFC 7518 spezifiziert). Somit wird das JWT nicht vom Server verifiziert, sondern einfach als valides JWT gesehen. Diese Sicherheitslücke wurde auch im CVE-2015-9235 festgehalten.
Eine weitere Attacke ist die Key Confusion Attack. Wie zuvor erwähnt wird der Parameter „kid“ benutzt, um Schlüssel zu kennzeichnen. Falls mehrere Schlüssel vorhanden sind, ist das von Vorteil. Wenn keine Key ID angegeben wird, wird ein Standardschlüssel benutzt. Stellen wir uns einen Server vor, welcher sowohl HS256 als auch RS256 als Algorithmen akzeptiert. Wenn allerdings keine Key ID in „kid“ angegeben ist, wird standardmäßig der öffentliche Schlüssel des RS256 für die Verifikation benutzt. Dies kann der Angreifer ausnutzen, indem er einen selbstsignierten JWT erstellt. Dazu lädt sich der Angreifer den öffentlichen Schlüssel des Servers herunter und benutzt diesen als Schlüssel für den symmetrischen Signierungsalgorithmus HS256. D.h. der Angreifer erstellt sich ein JWT mit einem Header und einem Payload und signiert diese mit dem HS256 Algorithmus, welcher als Schlüssel allerdings den öffentlichen RSA Schlüssel des Servers benutzt. Die berechnete Signatur hängt der Angreifer an sein JWT an und sendet diesen zum Server. Der Server sieht in dem JWT keine Key ID und benutzt nun seinen öffentlichen Schlüssel für die Verifikation. Da im Header der Algorithmus HS256 angegeben wird, wird dieser auch für die Verifikation benutzt. Das JWT wird als gültiges Token befunden und der Angriff hatte Erfolg.
Gegenmaßnahmen
Die Gegenmaßnahme, welche beide Angriffe verhindert, ist es niemals dem Input von Nutzern zu vertrauen. Der „alg“ Parameter kann beispielsweise durch eine Whitelist mit zugehörigen Key IDs vorgegeben sein, sodass der „none“ Algorithmus nicht benutzt werden kann. Durch die zusätzliche Vorgabe von Schlüsseln, benutzen die Algorithmen auch immer den richtigen Schlüssel.