Jwt None Algorithmus Angriff: Anwendung, typische Fehler, Praxiswissen und saubere Workflows
Was der None-Algorithmus bei JWT technisch bedeutet
alg umgehen. Ein JWT mit {"alg":"none"} signalisiert formal, dass keine kryptografische Signatur vorhanden ist. In bestimmten Spezifikationskontexten kann ein ungesichertes Token existieren, in produktiven Authentifizierungs- und Autorisierungssystemen ist das jedoch praktisch immer ein Fehlkonzept.
Der Angriff entsteht, wenn ein Server dem vom Client gelieferten Header vertraut und daraus ableitet, wie die Prüfung erfolgen soll. Genau dort liegt der Denkfehler: Der Angreifer kontrolliert das Token vollständig. Wenn die Anwendung also aus dem Token selbst liest, ob eine Signatur geprüft werden muss, wird die Sicherheitsentscheidung an untrusted input delegiert. Das ist funktional vergleichbar mit einer Zugriffskontrolle, die vom Benutzer selbst aktiviert oder deaktiviert werden kann.
Ein JWT mit None-Algorithmus hat typischerweise die Form base64url(header).base64url(payload).. Der dritte Teil ist leer oder fehlt logisch als Signaturinhalt. Wenn eine Bibliothek oder ein Wrapper diesen Zustand akzeptiert und die Claims trotzdem als authentisch behandelt, ist die Authentizität vollständig gebrochen. Dann lassen sich Benutzerrollen, User-IDs, Tenant-Zuordnungen, E-Mail-Adressen, Berechtigungen oder Ablaufzeiten frei manipulieren.
Für das technische Grundverständnis lohnt sich ein Blick auf Aufbau, Jwt Header Payload Signature und Jwt Signatur Erklaerung. Entscheidend ist: Base64URL ist nur Kodierung, keine Sicherheit. Wer ein Token dekodieren kann, kann es auch neu zusammensetzen. Sicherheit entsteht ausschließlich durch eine korrekt erzwungene Verifikation.
In realen Umgebungen taucht der Fehler meist nicht mehr in aktuellen Kernbibliotheken auf, sondern in Eigenimplementierungen, Legacy-Code, falsch konfigurierten Middleware-Ketten oder unsauberen Migrationspfaden. Besonders gefährlich sind Hilfsfunktionen, die Token zunächst nur „lesen“ und später versehentlich als bereits geprüft weiterreichen. Aus einem Parsing-Schritt wird dann unbemerkt ein Authentifizierungs-Schritt.
Header:
{
"typ": "JWT",
"alg": "none"
}
Payload:
{
"sub": "1001",
"email": "admin@example.local",
"role": "admin"
}
Token:
eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJzdWIiOiIxMDAxIiwiZW1haWwiOiJhZG1pbkBleGFtcGxlLmxvY2FsIiwicm9sZSI6ImFkbWluIn0.
Wenn ein Backend dieses Token akzeptiert, ist keine kryptografische Hürde mehr vorhanden. Der Angriff ist dann kein Brute-Force-Problem und kein Kryptoangriff, sondern ein reiner Logikfehler in der Vertrauenskette.
Wie der Angriff in echten Anwendungen entsteht
alg=none geändert, die Payload manipuliert und die Signatur entfernt. Danach wird das Token erneut an die Anwendung gesendet. Ob der Angriff funktioniert, hängt von mehreren Implementierungsdetails ab: akzeptiert die Bibliothek none, wird die Signaturprüfung optional behandelt, wird nur dekodiert statt verifiziert, oder existiert eine vorgelagerte Komponente, die Claims ungeprüft in den Request-Kontext schreibt.
Ein häufiger Fehler ist die Vermischung von Parsing und Verifikation. Viele Bibliotheken bieten Funktionen zum Dekodieren eines Tokens, um Claims auszulesen, ohne die Signatur zu prüfen. Das ist für Debugging oder Logging legitim, aber hochriskant, wenn das Ergebnis später für Autorisierung oder Session-Aufbau verwendet wird. Genau an dieser Stelle entstehen produktive Schwachstellen. Wer nur dekodiert, besitzt noch keinen Vertrauensbeweis. Für Analysezwecke sind Jwt Token Anleitung und Analysieren nützlich, aber im Auth-Flow darf Dekodierung nie mit Verifikation verwechselt werden.
Ein weiterer Fehler ist die dynamische Algorithmuswahl anhand des Token-Headers. Sichere Implementierungen definieren serverseitig, welche Algorithmen zulässig sind. Unsichere Implementierungen lesen alg aus dem Header und konfigurieren die Prüfung danach. Damit bestimmt der Angreifer das Prüfverfahren. Beim None-Angriff ist das besonders offensichtlich, aber dieselbe Denkschwäche führt auch zu Varianten wie Jwt Key Confusion Angriff oder Jwt Signature Bypass.
In Microservice-Landschaften verschärft sich das Problem. Ein API-Gateway validiert vielleicht korrekt, ein nachgelagerter Service vertraut aber blind auf weitergereichte Claims oder akzeptiert Tokens erneut mit schwacher Logik. Dadurch entsteht eine Sicherheitslücke nicht im zentralen Auth-Service, sondern an einer internen Vertrauensgrenze. Besonders kritisch ist das in Umgebungen mit Jwt API Authentication oder Jwt Microservices Authentication, wenn Teams unterschiedliche Libraries oder Middleware-Versionen einsetzen.
- Die Anwendung dekodiert Tokens, prüft aber die Signatur nicht verbindlich.
- Der erlaubte Algorithmus wird aus dem Token-Header übernommen statt serverseitig festgelegt.
- Claims aus ungeprüften Tokens werden in Session-Objekte, Security-Contexts oder Header übernommen.
- Interne Services vertrauen Tokens erneut, obwohl die ursprüngliche Verifikation nicht nachweisbar ist.
Der Angriff ist deshalb so gefährlich, weil er oft nicht als „Hacking“ im klassischen Sinn auffällt. Es gibt keinen lauten Exploit, keine Speicherfehler, keine auffälligen Payloads. Das Token sieht formal korrekt aus, nur die Vertrauensannahme ist falsch.
Praktischer Testablauf im Pentest ohne blinde Zerstörung
Im nächsten Schritt wird ein gültiges Token abgefangen und vollständig analysiert. Relevant sind Header-Felder wie alg, typ, kid sowie Claims wie sub, iss, aud, exp, nbf, iat, scope und anwendungsspezifische Rollenfelder. Für diesen Schritt helfen Lesen, Debugging und Pruefen als methodische Referenz.
Danach wird ein Testtoken erzeugt, bei dem nur eine Variable verändert wird. Zuerst wird der Header auf alg":"none" gesetzt, die Signatur entfernt und die Payload unverändert gelassen. Wenn dieses Token bereits akzeptiert wird, ist die Schwachstelle bestätigt. Wird es abgelehnt, folgt ein zweiter Test mit minimaler Claim-Manipulation, etwa einer harmlosen Änderung an einem nicht privilegierten Feld. Erst wenn die Anwendung weiterhin reagiert, werden sicherheitsrelevante Claims angepasst, beispielsweise role=user zu role=admin. Dabei muss jeder Schritt nachvollziehbar dokumentiert werden.
# Ursprüngliches Token
HEADER = {"alg":"HS256","typ":"JWT"}
PAYLOAD = {"sub":"1001","role":"user"}
# Testvariante
HEADER = {"alg":"none","typ":"JWT"}
PAYLOAD = {"sub":"1001","role":"user"}
# Eskalationsvariante
HEADER = {"alg":"none","typ":"JWT"}
PAYLOAD = {"sub":"1001","role":"admin"}
Wichtig ist die Beobachtung der Serverreaktion. Ein HTTP 200 allein reicht nicht als Nachweis. Entscheidend ist, ob sich Berechtigungen, Antwortdaten, UI-Elemente oder API-Funktionen tatsächlich ändern. Ein valides Ergebnis liegt erst vor, wenn die Anwendung Claims aus dem manipulierten Token wirksam übernimmt. In vielen Fällen zeigt sich das über zusätzliche Endpunkte, Admin-Menüs, fremde Datensätze oder erweiterte Scopes.
Ein professioneller Test vermeidet unnötige Seiteneffekte. Keine Löschoperationen, keine produktiven Änderungen an Benutzerkonten, keine Massenanfragen. Stattdessen werden lesende Endpunkte, Profilansichten oder harmlose Verwaltungsfunktionen genutzt. Für kontrollierte Übungen kann zusätzlich Jwt Token Test herangezogen werden, um Manipulationspfade systematisch nachzustellen.
Typische Fehlannahmen in Entwicklung und Betrieb
Ein weiterer Irrtum ist die Annahme, dass Base64-kodierte Daten „irgendwie geschützt“ seien. JWTs wirken für viele Teams kryptisch, weil sie kompakt und maschinenlesbar aussehen. Tatsächlich sind Header und Payload trivial lesbar. Wer das Grundprinzip nicht sauber trennt, verwechselt Datenformat mit Sicherheitsmechanismus. Die Inhalte werden nicht durch das Tokenformat geschützt, sondern nur durch die Signatur gegen unbemerkte Veränderung abgesichert.
Ebenso problematisch ist die Aussage: „Die Bibliothek prüft das schon.“ Bibliotheken können sicher sein, aber nur bei korrekter Verwendung. Viele Schwachstellen entstehen in Wrappern, Middleware-Konfigurationen oder selbstgebauten Hilfsfunktionen. Ein Beispiel: Ein Entwickler nutzt eine Decode-Funktion, extrahiert Claims und prüft nur, ob exp in der Zukunft liegt. Damit wird zwar eine Ablaufzeit beachtet, aber keine Authentizität hergestellt. Ein Angreifer setzt einfach eine neue Zukunftszeit.
Auch Logging- und Debugging-Code wird oft unterschätzt. In Staging- oder Testumgebungen werden Verifikationen manchmal deaktiviert, um Integrationen zu beschleunigen. Später wandert derselbe Code in produktionsnahe Deployments oder wird per Feature-Flag nicht sauber abgeschaltet. Solche Übergänge sind in Audits regelmäßig sichtbar, besonders wenn mehrere Teams an Jwt Implementierung und Jwt Authentication beteiligt sind.
Ein weiterer Klassiker ist die falsche Priorisierung von Claims. Manche Systeme behandeln sub als Identität und ignorieren Rollen, andere vertrauen direkt auf role, permissions oder is_admin. Wenn diese Felder aus einem ungeprüften Token stammen, ist die gesamte Autorisierung kompromittiert. Das Problem ist also nicht nur Authentifizierung, sondern unmittelbar auch Rechtevergabe und Mandantentrennung.
In Reviews sollte deshalb immer gefragt werden: Wo genau wird aus „Token empfangen“ der Zustand „Benutzer ist authentifiziert“? Wenn diese Übergangsstelle nicht eindeutig an eine erfolgreiche Signaturprüfung gebunden ist, besteht ein strukturelles Risiko.
Erkennung im Code: unsichere Muster und belastbare Gegenmuster
decode(), parse() oder readClaims(), deren Rückgabewerte später in Security-Kontexte übernommen werden. Kritisch ist jede Stelle, an der Claims ohne expliziten Verifikationsstatus weitergereicht werden. Wenn ein Objekt wie jwtPayload oder userClaims im Request-Kontext landet, ohne dass eine erfolgreiche Signaturprüfung technisch erzwungen wurde, ist Vorsicht geboten.
Ein weiteres Warnsignal ist die Übergabe von Optionen wie verify=false, ignoreSignature=true oder das Fehlen einer festen Algorithmusliste. Ebenso verdächtig sind Catch-Blöcke, die bei Verifikationsfehlern „degradiert“ weiterarbeiten, etwa indem sie nur eine Warnung loggen und den Request trotzdem zulassen. In Legacy-Systemen findet sich oft ein Fallback: Wenn die Signaturprüfung fehlschlägt, wird das Token trotzdem dekodiert, um „zumindest die User-ID“ zu erhalten. Genau solche Fallbacks öffnen den Weg für None-Tokens.
- Unsicher: Algorithmus aus dem Header lesen und dynamisch akzeptieren.
- Unsicher: Token dekodieren und Claims direkt für Rollen oder Benutzeridentität verwenden.
- Sicher: Erlaubte Algorithmen serverseitig fest definieren und jede Abweichung hart ablehnen.
- Sicher: Nur verifizierte Claims in Auth- oder Autorisierungskontexte übernehmen.
Belastbare Gegenmuster sind klar: Verifikation muss ein zwingender Gatekeeper sein. Der Codepfad darf keine Claims liefern, wenn die Signaturprüfung nicht erfolgreich war. Außerdem muss die Anwendung den erwarteten Algorithmus selbst festlegen. Wer HS256 nutzt, akzeptiert nur HS256. Wer RS256 nutzt, akzeptiert nur RS256. Mischbetrieb ohne klare Trennung erhöht das Risiko zusätzlicher Fehler, etwa bei Jwt Algorithmen Hs256 Rs256 oder Jwt Symmetrisch Vs Asymmetrisch.
// Unsicheres Muster
token = getAuthorizationHeader()
claims = decode(token) // keine Signaturprüfung
if claims.exp > now():
request.user = claims.sub
request.role = claims.role
// Sicheres Muster
token = getAuthorizationHeader()
claims = verify(token, expectedAlg="RS256", publicKey=trustedKey)
request.user = claims.sub
request.role = claims.role
Im Review sollte außerdem geprüft werden, ob vorgelagerte Komponenten wie API-Gateways, Reverse Proxies oder Service Meshes JWT-Claims in Header transformieren. Wenn Backend-Services diese Header akzeptieren, ohne die Herkunft kryptografisch oder netzwerkseitig abzusichern, kann ein None-Angriff indirekt über manipulierte Claims wirksam werden.
Auswirkungen auf Autorisierung, Mandantentrennung und API-Sicherheit
Besonders kritisch ist die Mandantentrennung. Viele SaaS-Systeme tragen eine tenant_id, org_id oder ähnliche Zuordnung im Token. Wird dieses Feld manipuliert und akzeptiert, kann ein Benutzer Daten eines anderen Mandanten lesen oder verändern. Das ist nicht nur ein Auth-Problem, sondern ein direkter Datenisolationsbruch mit hohem Schadenspotenzial. In Audits ist das regelmäßig schwerwiegender als eine reine Rolleneskalation innerhalb desselben Kontos.
Auch Scope-basierte APIs sind anfällig. Ein Token mit scope=read:profile wird zu scope=admin:all, und schon öffnet sich ein ganzer Satz privilegierter Endpunkte. Wenn zusätzlich Business-Logik auf Claims wie department, region oder support_level vertraut, lassen sich interne Grenzen umgehen, ohne dass klassische Zugriffskontrollen anschlagen. Das Problem betrifft daher nicht nur Security-Teams, sondern auch Fachlogik und Datenmodellierung.
In Zero-Trust-Architekturen ist der Fehler besonders widersprüchlich. Dort soll jede Anfrage explizit validiert werden. Wenn aber ein interner Service ungeprüfte JWT-Claims akzeptiert, wird das Modell unterlaufen. Ein sauberer Bezug zu Jwt Zero Trust und Jwt Security Architektur zeigt, dass Token nur dann als Vertrauensartefakte taugen, wenn ihre Herkunft und Integrität an jeder relevanten Grenze verlässlich geprüft werden.
Praktisch bedeutet das: Ein erfolgreicher None-Angriff kann zu Account-Übernahme, horizontaler und vertikaler Rechteausweitung, Datenabfluss, Manipulation von Geschäftsprozessen und Missbrauch interner APIs führen. In Incident-Analysen ist oft sichtbar, dass die erste Auffälligkeit nicht der Login selbst war, sondern ungewöhnliche API-Aufrufe mit formal gültig aussehenden, aber ungesicherten Tokens.
Saubere Verifikation: was serverseitig zwingend erzwungen werden muss
Verifikation umfasst mehr als die Signatur. Nach erfolgreicher kryptografischer Prüfung müssen auch iss, aud, exp, nbf und je nach Anwendung azp, scope oder benutzerdefinierte Claims validiert werden. Ein Token kann korrekt signiert, aber dennoch für die falsche Zielanwendung oder außerhalb des gültigen Zeitfensters ausgestellt sein. Deshalb gehören Verifikation und Validierung zusammen, aber sie sind nicht identisch.
Wichtig ist außerdem die Trennung von Token-Typen. Access Tokens, ID Tokens, Refresh Tokens und interne Service Tokens dürfen nicht mit derselben Logik blind austauschbar sein. Wenn ein Service nur Access Tokens akzeptieren soll, muss er genau das prüfen. Sonst entstehen zusätzliche Missbrauchspfade, die zwar nicht direkt None-basiert sind, aber aus derselben laxen Vertrauenshaltung resultieren.
- Erwarteten Algorithmus serverseitig fest konfigurieren und keine automatische Aushandlung zulassen.
- Tokens mit
alg=nonein produktiven Auth-Flows grundsätzlich hart ablehnen. - Nur verifizierte Claims an nachgelagerte Komponenten weitergeben.
- Issuer, Audience, Zeitfenster und Token-Typ zusätzlich zur Signatur prüfen.
In modernen Stacks sollte die Verifikation in einer zentralen, getesteten Komponente stattfinden. Nicht jeder Controller, Resolver oder Microservice sollte eigene JWT-Logik implementieren. Zentralisierung reduziert Inkonsistenzen und verhindert, dass einzelne Teams aus Bequemlichkeit unsichere Shortcuts einbauen. Ergänzend helfen Jwt Best Practices und Jwt Security als Leitlinie für robuste Standards.
Ein weiterer Punkt ist Fail-Closed-Verhalten. Wenn Schlüssel nicht geladen werden können, wenn das JWKS nicht erreichbar ist oder wenn der Header unerwartete Werte enthält, muss die Anfrage abgelehnt werden. Jede Form von „temporär trotzdem akzeptieren“ ist in Auth-Systemen brandgefährlich.
Forensik und Fehlersuche: wie ein None-Problem im Betrieb auffällt
Für die Analyse sollten eingehende Tokens oder zumindest deren sicherheitsrelevante Metadaten protokolliert werden, ohne sensible Inhalte unnötig offenzulegen. Relevant sind Header-Algorithmus, Issuer, Audience, Subject, Token-ID, Ergebnis der Signaturprüfung und der konkrete Ablehnungsgrund. Wenn Logs nur „JWT invalid“ enthalten, fehlt die Grundlage für schnelle Ursachenanalyse. Gleichzeitig dürfen vollständige Tokens nicht unkontrolliert in zentrale Logsysteme geschrieben werden, weil sie selbst sensible Daten oder aktive Zugangstoken enthalten können.
Ein starkes Signal ist jede Beobachtung von alg=none in produktiven Requests. In normalen Auth-Flows sollte das praktisch nicht vorkommen. Ebenso verdächtig sind Requests, bei denen Claims verarbeitet wurden, obwohl die Verifikation fehlgeschlagen ist oder gar nicht dokumentiert wurde. Gute Telemetrie trennt daher klar zwischen „Token gelesen“, „Signatur geprüft“, „Claims validiert“ und „Benutzerkontext erstellt“.
{
"event": "jwt_auth",
"alg_header": "none",
"signature_verified": false,
"claims_validated": false,
"request_allowed": true,
"subject": "1001",
"role": "admin"
}
Ein solcher Logeintrag wäre ein unmittelbarer Incident-Hinweis. In der Praxis sind die Daten oft weniger eindeutig, etwa wenn Middleware A das Token nur dekodiert und Middleware B annimmt, die Prüfung sei bereits erfolgt. Deshalb ist End-to-End-Transparenz wichtig: Welche Komponente hat verifiziert, mit welchem Schlüssel, gegen welche Policy und mit welchem Ergebnis?
Bei der Fehlersuche helfen reproduzierbare Testfälle in isolierten Umgebungen. Ein bekanntes gültiges Token wird in mehreren Varianten gegen dieselbe Route getestet: unverändert, mit ungültiger Signatur, mit alg=none, mit verändertem iss, mit abgelaufenem exp. Wenn die Antworten nicht sauber differenzieren, ist die Verifikationskette wahrscheinlich unscharf. Für tieferes Troubleshooting sind Jwt Fehler Und Probleme und Validieren Online als methodische Ergänzung hilfreich.
Praxisnahe Härtung für Node.js, Python, PHP und verteilte Systeme
req.user hängen. In Python entstehen ähnliche Probleme durch die Verwechslung von Decode- und Verify-Funktionen. In PHP sind Legacy-Snippets besonders riskant, weil dort häufig kompakte Hilfsfunktionen aus alten Tutorials übernommen werden.
Unabhängig von der Sprache gilt: Die Verifikation gehört in eine zentrale Komponente, idealerweise mit klarer API wie verifyAccessToken(token). Diese Funktion sollte nur dann Claims zurückgeben, wenn alle Prüfungen erfolgreich waren. Kein optionaler Schalter für „nur lesen“, kein stilles Fallback, keine automatische Algorithmuswahl. Für stack-spezifische Umsetzungspfade können Jwt Nodejs, Jwt Python und Jwt Php als technische Bezugspunkte dienen.
In verteilten Systemen ist zusätzlich wichtig, wie verifizierte Identität weitergereicht wird. Wenn ein Gateway das JWT prüft und danach interne Header wie X-User-Id oder X-Role setzt, müssen Backend-Services sicherstellen, dass diese Header nur vom Gateway kommen können. Sonst reicht ein direkter Zugriff auf den Service, um dieselben Header zu fälschen. Das Problem verschiebt sich dann von JWT auf Netzwerk- und Vertrauensgrenzen.
Auch Schlüsselmanagement spielt hinein. Bei asymmetrischen Verfahren müssen Public Keys aus vertrauenswürdigen Quellen geladen und gegen erwartete Issuer gebunden werden. Bei symmetrischen Verfahren muss das Secret ausreichend stark, geschützt gespeichert und sauber rotiert werden. Zwar verhindert gutes Schlüsselmanagement allein keinen None-Angriff, aber unsaubere Schlüssel- und Algorithmuslogik treten oft gemeinsam auf.
Ein robuster Workflow in Teams umfasst feste Security-Tests für jede Änderung an Auth-Middleware, Regressionstests gegen manipulierte Tokens und Code-Reviews mit Fokus auf Vertrauensgrenzen. Wer JWTs einsetzt, sollte nicht nur die Funktionsweise verstehen, sondern auch die typischen Missbrauchspfade aus Jwt Angriffe und Sicherheitsluecken systematisch abdecken.
Sauberer Workflow für Tests, Fixes und nachhaltige Absicherung
Der Fix selbst sollte aus mehreren Schichten bestehen. Erstens: harte Ablehnung von alg=none in allen produktiven Auth-Flows. Zweitens: feste serverseitige Algorithmus-Policy. Drittens: zentrale Verifikationslogik ohne Decode-Bypass. Viertens: Regressionstests, die manipulierte Tokens dauerhaft abdecken. Fünftens: Review aller nachgelagerten Komponenten, die Claims oder daraus abgeleitete Header konsumieren.
Ein sinnvoller Testkatalog enthält mindestens folgende Fälle: gültiges Token, Token mit ungültiger Signatur, Token mit alg=none, Token mit falschem Issuer, Token mit falscher Audience, abgelaufenes Token, Token mit manipulierten Rollen und Token mit unerwartetem Typ. Diese Tests gehören in CI/CD, nicht nur in einmalige manuelle Prüfungen. So wird verhindert, dass spätere Refactorings alte Fehler wieder einführen.
Zusätzlich sollte die Architektur hinterfragt werden. Nicht jede Anwendung profitiert von JWTs. In manchen Szenarien sind serverseitige Sessions einfacher und weniger fehleranfällig. Der Vergleich mit Jwt Session Vs Jwt hilft, unnötige Komplexität zu vermeiden. Wenn JWTs sinnvoll sind, müssen Lebensdauer, Rotation, Widerruf und Schlüsselwechsel sauber geregelt sein, etwa über Jwt Refresh Token, Jwt Rotation und Jwt Revocation.
Nach der Behebung ist ein Retest Pflicht. Dabei wird nicht nur der ursprüngliche None-Pfad geprüft, sondern auch verwandte Schwachstellen wie Algorithmusverwechslung, fehlende Audience-Prüfung oder ungesicherte interne Header. Erst wenn die gesamte Vertrauenskette konsistent ist, gilt das Problem als nachhaltig behoben. Genau darin liegt der Unterschied zwischen einem schnellen Patch und einer belastbaren Sicherheitsmaßnahme.
Weiter Vertiefungen und Link-Sammlungen
Passende Vertiefungen, Vergleiche und angrenzende JWT-Token-Themen:
Passender Lernpfad:
Passende Erweiterungen:
Passende Lernbundels:
Passende Zertifikate: