In this article
CVE-2026-29000: Wie ein öffentlicher Schlüssel die Authentifizierung in pac4j-jwt aushebelt
Eine kritische Authentifizierungsumgehung in der Java-Sicherheitsbibliothek pac4j-jwt ermöglicht es Angreifern, sich als beliebige Benutzer, einschließlich Administratoren, auszugeben – und dazu benötigen sie nichts weiter als den öffentlichen RSA-Schlüssel eines Servers. Die als CVE-2026-29000 erfasste Schwachstelle hat einen CVSS-Score von 10.0 und betrifft alle Versionen von org.pac4j:pac4j-jwt vor 4.5.9, 5.7.9 und 6.3.3.
Die Schwachstelle lässt sich leicht ausnutzen. Ein öffentlicher Proof of Concept ist verfügbar, und gepatchte Versionen sind bereits erhältlich. Wenn Ihre Java-Anwendung pac4j für die JWT-basierte Authentifizierung verwendet, lesen Sie weiter.
Kurzfassung
Detail | Wert |
|---|---|
CVE | |
CVSS 3.1 | 10.0 Kritisch ( |
CVSS 4.0 | 10.0 Kritisch ( |
CWE | CWE-347: Unzureichende Überprüfung kryptografischer Signaturen |
Maven-Artefakt |
|
Betroffen | 4.x \< 4.5.9, 5.0.0-RC1 \< 5.7.9, 6.0.4.1 \< 6.3.3 |
Behoben | 4.5.9, 5.7.9, 6.3.3 |
Exploit-Status | Öffentlicher PoC verfügbar |
Entdeckt von | CodeAnt AI Security Research |
Was ist pac4j?
pac4j ist ein Sicherheits-Framework für Java, das Authentifizierung und Autorisierung für verschiedene Protokolle bereitstellt: OAuth, SAML, CAS, OpenID Connect und JWT. Das Modul pac4j-jwt übernimmt speziell die Erstellung und Validierung von JSON Web Token über die Klasse JwtAuthenticator.
pac4j kann als zugrunde liegende Authentifizierungs-Engine in Frameworks wie Spring Security, JEE, Play, Vert.x und weiteren verwendet werden. Es ist auch in CAS-Umgebungen (Central Authentication Service) weit verbreitet, wie sie häufig an Universitäten und in Behörden zum Einsatz kommen. Wenn Ihre Anwendung eine pac4j-basierte JWT-Authentifizierung verwendet, ist sie möglicherweise betroffen.
So funktioniert die Schwachstelle
Um diese Schwachstelle zu verstehen, müssen Sie den Unterschied zwischen zwei JWT-Typen kennen:
JWS (JSON Web Signature): Ein signiertes Token. Die Signatur belegt, dass das Token nicht manipuliert wurde und von jemandem mit dem Signaturschlüssel erstellt wurde.
JWE (JSON Web Encryption): Ein verschlüsseltes Token. Die Verschlüsselung schützt den Inhalt des Tokens davor, während der Übertragung gelesen zu werden. Ein JWE kann ein JWS umschließen und so sowohl Vertraulichkeit als auch Integrität gewährleisten.
Wenn der JwtAuthenticator von pac4j ein verschlüsseltes JWT (JWE) empfängt, geht die Bibliothek folgendermaßen vor:
Äußere JWE-Hülle entschlüsseln
Inneren Payload parsen
Signatur des inneren Tokens überprüfen
Die Schwachstelle liegt in Schritt 3. Nach dem Entschlüsseln des JWE ruft die Bibliothek die Funktion toSignedJWT() von com.nimbusds:nimbus-jose-jwt für den inneren Payload auf, um das signierte Token zur Überprüfung auszulesen. Ist das innere Token ein PlainJWT (ein JWT mit alg: none, also ohne Signatur), gibt diese Methode null zurück.
Im verwundbaren Code führte dieser Null-Wert dazu, dass der gesamte Block zur Signaturüberprüfung übersprungen wurde. Die Bibliothek verhielt sich im Grunde so: „Ich finde keine Signatur, die ich überprüfen kann, also mache ich einfach weiter.“
Hier sehen Sie eine vereinfachte Darstellung der verwundbaren Logik:
// (after JWE decryption succeeds above)
SignedJWT signedJWT = encryptedJWT.getPayload().toSignedJWT();
// If inner token is PlainJWT, signedJWT is null
if (signedJWT != null) {
jwt = signedJWT;
}
// Signature verification only runs if signedJWT is not null
if (signedJWT != null && !signatureConfigurations.isEmpty()) {
// Verify signature... but this block is NEVER entered
// for a PlainJWT wrapped in JWE
}
// Claims are extracted regardless — attacker is now "authenticated"
createJwtProfile(ctx, credentials, jwt);Die Korrektur weist ein nicht signiertes Token in einer verschlüsselten Hülle explizit zurück:
if (!signatureConfigurations.isEmpty()) {
if (signedJWT == null) {
throw new CredentialsException(
"A non-signed JWT cannot be accepted...");
}
// Proceed with normal signature verification
}Der Angriff in der Praxis
Ein Angreifer benötigt nur eines: den öffentlichen RSA-Schlüssel des Servers. Öffentliche Schlüssel sind definitionsgemäß … öffentlich. Sie sind oft in JWKS-Endpunkten, Zertifikaten oder Konfigurationsdateien eingebunden.
Die Angriffsschritte:
Den öffentlichen RSA-Schlüssel des Servers beschaffen (über einen JWKS-Endpunkt, ein TLS-Zertifikat oder eine andere öffentliche Quelle)
Ein PlainJWT erstellen mit beliebigen Claims:
{
"sub": "admin",
"role": "ADMIN",
"exp": 1772611200
}Das Token in ein JWE einschließen, das mit dem öffentlichen RSA-Schlüssel des Servers verschlüsselt wird
Das gefälschte Token an die Anwendung senden
Die Anwendung entschlüsselt das JWE (die Verschlüsselung mit dem öffentlichen Schlüssel ist gültig), findet keine zu überprüfende Signatur, überspringt die Überprüfung und akzeptiert die gefälschten Claims als authentisch
Der Angreifer benötigt weder den privaten Schlüssel noch ein gemeinsames Geheimnis oder irgendwelche Zugangsdaten. Als einzige Voraussetzung genügt der öffentliche Schlüssel, der das System eigentlich schützen sollte.
Wer ist betroffen?
Sie sind möglicherweise betroffen, wenn:
Sie RSA-Verschlüsselung verwenden. Dies lässt sich im Projekt anhand von RSAEncryptionConfiguration erkennen.
Ihre Anwendung
org.pac4j:pac4j-jwtfür die JWT-Authentifizierung verwendetSie in Ihrem
JwtAuthenticatorsowohl Verschlüsselungs- (JWE) als auch Signaturüberprüfungskonfigurationen (JWS) verwendenbeideSie eine Version vor 4.5.9, 5.7.9 oder 6.3.3 einsetzen
Anwendungen, die ausschließlich signierte JWTs (JWS) ohne Verschlüsselung verwenden, sind für diesen konkreten Angriff nicht anfällig, da der Trick mit einem PlainJWT in einem JWE eine konfigurierte Verschlüsselung voraussetzt.
Mit Snyk prüfen
Mit der Snyk CLI können Sie prüfen, ob Ihr Projekt betroffen ist:
# For Maven projects
snyk test --maven
# For Gradle projects
snyk test --gradleSnyk erfasst diese Schwachstelle unter SNYK-JAVA-ORGPAC4J-15428218. Befindet sich das verwundbare Paket in Ihrem Abhängigkeitsbaum, weist Snyk darauf hin und empfiehlt einen Upgrade-Pfad.
Wenn Sie Maven verwenden, kann das Snyk Maven plugin die Schwachstelle im Rahmen Ihres Build-Zyklus ebenfalls erkennen, ohne dass ein separater CLI-Schritt erforderlich ist. Für Gradle-Projekte bietet das Snyk Gradle plugin dieselbe integrierte Scan-Funktion.
Sie können Ihre Abhängigkeiten auch direkt durchsuchen:
# Check if pac4j-jwt is in your dependency tree
mvn dependency:tree | grep pac4j-jwt
# Or with Gradle
gradle dependencies | grep pac4j-jwtBehebung
Aktualisieren Sie org.pac4j:pac4j-jwt auf die gepatchte Version für Ihre Hauptversionsreihe:
Aktuelle Version | Aktualisieren auf |
|---|---|
4.x | 4.5.9 oder höher |
5.x | 5.7.9 oder höher |
6.x | 6.3.3 oder höher |
Aktualisieren Sie für Maven Ihre pom.xml:
<!-- For pac4j 6.x -->
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>pac4j-jwt</artifactId>
<version>6.3.3</version>
</dependency>Für Gradle:
// For pac4j 6.x
implementation 'org.pac4j:pac4j-jwt:6.3.3'Wenn Sie nicht sofort aktualisieren können
Ein Upgrade wird dringend empfohlen. Bis dahin können Sie Ihr Risiko verringern, indem Sie:
Ihre JWT-Konfiguration überprüfen: Wenn Ihre Anwendung ausschließlich signierte JWTs (JWS) ohne Verschlüsselung verwendet, ist sie für diesen konkreten Angriffsweg nicht anfällig. Ein Upgrade ist dennoch die sicherste Vorgehensweise.
Den JWT-Verarbeitungscode überprüfen: Stellen Sie sicher, dass Ihre Anwendung signierte Token explizit voraussetzt und nicht signierte Token auf Anwendungsebene zurückweist.
In den verwundbaren Versionen gibt es innerhalb von pac4j selbst keine Abhilfe über die Konfiguration.
Warum das über pac4j hinaus wichtig ist
Diese Schwachstelle ist ein typisches Beispiel für eine umfassendere Klasse von Implementierungsfehlern bei JWT. Das Grundproblem – das Fehlen einer Sicherheitseigenschaft (einer Signatur) als Anlass zum Überspringen statt zum Zurückweisen zu behandeln – ist seit Jahren in JWT-Bibliotheken verschiedener Programmiersprachen zu beobachten.
Die Lehre daraus ist eindeutig: Kryptografische Überprüfungen müssen verpflichtend und dürfen nicht optional sein. Wenn eine Bibliothek ein nicht signiertes Token vorfindet, obwohl ein signiertes erwartet wird, ist Zurückweisung die einzig sichere Reaktion. Ein stillschweigendes Weitermachen ist eine Schwachstelle, die nur darauf wartet, ausgenutzt zu werden. Erfahren Sie mehr darüber, wie sich Authentifizierungsfehler dieser Art äußern, in der Lektion Broken Authentication auf Snyk Learn.
Für Java-Teams heißt das:
Akzeptierte Algorithmen explizit konfigurieren bei der JWT-Validierung. Erlauben Sie niemals
none.Verschlüsselung und Signierung als voneinander unabhängige Aufgaben betrachten. Die Entschlüsselung belegt Vertraulichkeit, nicht Authentizität. Auch bei einem in ein JWE eingebetteten Token muss die Signatur überprüft werden.
Transitive Abhängigkeiten regelmäßig überprüfen. pac4j-jwt kann durch eine Framework-Integration eingebunden werden, die Sie nicht direkt verwalten. Hinweise zur Überprüfung Ihres Abhängigkeitsbaums finden Sie unter Best Practices for Managing Java Dependencies.
Weitere Informationen zum sicheren Umgang mit JWT finden Sie in den Artikeln Top 3 Security Best Practices for Handling JWTs und Can Snyk Detect JWT Security Issues? im Snyk-Blog.
Zeitachse
Datum | Ereignis |
|---|---|
2. März 2026 | Der Maintainer des pac4j-jwt-Projekts veröffentlichte Patches |
3. März 2026 | Der Maintainer des pac4j-jwt-Projekts veröffentlichte einen Sicherheitshinweis und einen Blogbeitrag |
4. März 2026 | CVE-Details auf MITRE veröffentlicht |
WHITEPAPER
Die KI-Sicherheitskrise in Ihrer Python-Umgebung
Angesichts des rasanten Entwicklungstempos: Wissen Sie wirklich, worauf Ihre KI-Umgebung zugreifen kann?