Ich möchte ein "Red Teaming"
Michael Schneider
So lassen sich signierte JSON Web Token kompromittieren
Ein JSON Web Token (JWT) ist ein nach RFC 7519 genormtes Access-Token, das Informationen als JSON-Objekt zwischen einzelnen Parteien transferiert. Die benötigten Informationen sind im Token enthalten, weshalb dieses beispielsweise für die Authentisierung oder den Informationsaustausch zwischen Front- und Backend eingesetzt werden können. Der Inhalt das Tokens ist base64url-codiert und somit sind die im JWT enthaltenen Informationen im Klartext verfügbar. Es besteht jedoch die Möglichkeit, dass JSON Web Token zu verifizieren und zu signieren, um eine Manipulation des Tokens möglichst zu verhindern.
Ein signiertes JSON Web Token besteht aus 3 Abschnitten, dem JOSE Header, der JWS Payload und der Signatur. Sie sind jeweils voneinander durch einen Punkt .
getrennt.
Beispiel eines JSON Web Tokens:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6InNjaXAgQUciLCJhZG1pbiI6dHJ1ZSwiaWF0IjoxNTE2MjM5MDIyfQ.dX_ACtDZVh9ZKaDMLmZFURrh7o5R99-6MEulWUFCaT0
Das JWT-Beispiel dekodiert:
{"alg": "HS256", "typ": "JWT"}
{"sub": "1234567890", "name": "scip AG", "admin": true, "iat": 1516239022}
dX_ACtDZVh9ZKaDMLmZFURrh7o5R99-6MEulWUFCaT0
(Verwendung des Secrets scipAG
)Der erste Teil eines JWT ist der JOSE (Javascript Object Signing and Encryption) Header. Er enthält Informationen darüber, mit welchem Algorithmus das Token signiert wurde. Ein Token kann beispielsweise mit HMAC-Algorithmen und einem Secret signiert werden oder mittels Public-/Private-Key-Verfahren wie RSA oder ECDSA. Alle verwendbaren Algorithmen sind in der Spezifikation JSON Web Algorithms (JWA) auffindbar.
Auffällig dabei ist der definierte Algorithmus none
. Es ist möglich ein JWT damit zu manipulieren, indem der Algorithmus auf {"alg":"none"}
gesetzt, sowie die Signatur entfernt wird. Sofern das Backend keine Signatur-Verifizierung durchführt, wird das manipulierte Token ohne weiteres angenommen. Die Verifizierung der Signatur ist aus diesem Grund unerlässlich, da ansonsten die Informationen in der Payload des Tokens nach Belieben geändert werden kann. Beispielsweise könnte mit dem Ändern der Benutzerrolle eine Privilege Escalation angestrebt werden.
Der zweite Abschnitt des Tokens, das JWT Claims Set, stellt ein JSON-Objekt dar, welches die zu übermittelnden Informationen (Claims) enthält. Es gibt drei Klassen von JWT Claims Names:
Die Namen müssen stets eindeutig sein, die vordefinierten Claims können im RFC 7519 eingesehen werden.
Auch die JWS-Payload ist base64url-kodiert, weshalb besonders darauf geachtet werden sollte, dass beispielsweise keine sensitiven Personendaten über ein JWT übermittelt werden. Ansonsten ist es einem Angreifer durch die Analyse eines JWTs möglich, diese Informationen in Erfahrung zu bringen, Aufschluss über die Struktur von Email-Adressen oder Usernamen zu erhalten oder auch die genaue Bezeichnung von Benutzerrollen zu erfahren. Denn die Signatur des Tokens verhindert lediglich die Manipulation des Tokens – die darin enthaltenen Informationen können jederzeit, quasi im Klartext, ausgelesen werden. Eine JWS Payload anzupassen ist unkompliziert. Burp Suite bietet beispielsweise diverse Extensions wie unter anderem JSON Web Tokens (JOSEPH) als Hilfestellung an.
Das dritte und letzte Element des Tokens ist die Signatur, deren Aufbau nach dem RFC 7515 genormten Standard, definiert ist. Auch die Signatur ist base64url-codiert und wurde mit dem gewählten Algorithmus aus dem JOSE-Header gebildet. Mithilfe der Signatur soll sichergestellt werden, dass ein Token während der Übermittlung nicht manipuliert wurde.
Die Signatur des JWTs kann jedoch ebenfalls Schwachstellen enthalten. Wurde der Algorithmus HS256 gewählt und ein schwaches Secret gesetzt, ist es möglich, letzteres zu errechnen. Insbesondere Hashcat stellt dafür eine entsprechende Funktion zur Verfügung (Hash Mode 16500).
./hashcat64.bin --session <project> -a 16500 -m <jwt> -w 3 -r <rulepath> <dictpath>
Sobald das Secret errechnet wurde, kann wiederum das Token beliebig manipuliert oder neu generiert und mit dem entsprechenden Secret signiert werden. Dabei kann auch ein online JWT-Generator beigezogen werden.
Im Allgemeinen gibt es Access- und Refresh-Tokens. Ist die Validierung der Access- und Refresh-Tokens nicht korrekt konfiguriert, ist es unter Umständen möglich, ein Access-Token (auch abgelaufenes) eines anderen Users mit dem eigenen Refresh-Token zu erneuern, sofern der Angreifer in den Besitz eines solchen gelangen kann. Dies ist dann möglich, wenn nur die Gültigkeit eines Refresh-Tokens überprüft wird und nicht seine Zugehörigkeit zum Access-Token.
Die Bedingungen für den Request sind Kenntnisse über den Endpunkt, wo ein neues Token generiert wird, ein Authorization: Bearer
Header mit dem entsprechend abgelaufenen Access-Token, sowie das Refresh-Token im Body des Requests.
Gestelltes Beispiel für die Erneuerung eines fremden Access-Tokens mit dem eigenen Refresh-Token:
POST /scipAG/JWT/refresh/newToken [Various Headers] Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6InNjaXAgQUciLCJhZG1pbiI6dHJ1ZSwiaWF0IjoxNTE2MjM5MDIyfQ.dX_ACtDZVh9ZKaDMLmZFURrh7o5R99-6MEulWUFCaT0 [Various Headers] {"refresh_token": "thisIsAnExampleOnly"}
Im Vergleich zu SAML (Security Assertion Markup Language) hat ein signiertes JSON Web Token den Vorteil, dass es einfach zu implementieren ist, da es aufgrund der geringen Grösse ohne Probleme in ein HTTP-Header passt. Im Gegenzug dazu ist es einem JWT nicht möglich, ein SAML vollständig zu ersetzen. SAML 2.0 bietet mehr Sicherheitsoptionen, welche jedoch mit einer höheren Komplexität und Grösse verbunden sind. Dabei tragen insbesondere die Verwendung von XML, XML Digital Signature (DSIG), sowie XML Canonicalization zur Komplexität von SAML bei.
Im Vergleich mit Simple Web Tokens (SWTs), bietet ein JWT mehr Flexibilität und Wahlmöglichkeiten. Während sowohl die Claim Names, sowie die Claim Values bei einem SWT das Format eines Strings aufweisen, können die Claim Values des JWT einen beliebigen JSON-Typ annehmen. Des Weiteren unterstützt das SWT nur HMAC SHA-256, wobei bei einem JWT zwischen verschiedenen Algorithmen gewählt werden kann.
Signierte JSON Web Tokens sind sicher, sofern sie korrekt und sorgfältig konfiguriert und implementiert werden. Wichtig zu beachten ist jedoch, dass keine sensitiven Informationen, wie Username, Benutzerrolle oder Ähnliches, über das Token transportiert werden. Denn diese sind nur mittels base64url-codiert und werden nicht verschlüsselt übertragen.
Unsere Spezialisten kontaktieren Sie gern!
Michael Schneider
Marisa Tschopp
Michèle Trebo
Andrea Covello
Unsere Spezialisten kontaktieren Sie gern!