Kai Ole Hartwig
20 Min. Lesezeit
Von

Keycloak CVE-2026-117691: Die Signatur gilt einer anderen SAML-Nachricht als der verarbeiteten

Beim HTTP-Redirect-Binding reist eine SAML-Nachricht in der URL, und ihre Signatur deckt eine Zeichenkette aus Query-Parametern ab, nicht das XML selbst. Bis Version 26.8.1 las Keycloak diese Parameter auf zwei verschiedene Arten. Die Signaturprüfung sah die rohe Query, die Verarbeitung eine Fassung mit dekodierten Parameternamen. Ein Parameter mit prozentkodiert geschriebenem Namen blieb so für die eine Seite unsichtbar und wurde für die andere zur eigentlichen Nachricht. CVE-2026-117691 macht daraus eine Anmeldung als beliebiger föderierter Nutzer, sobald ein Angreifer eine einzige gültig signierte Antwort des Identity Providers in der Hand hat. Keycloak 26.8.2 vereinheitlicht deshalb das Parsing und prüft zusätzlich, ob der signierte Wert auch der verarbeitete ist.

TL;DR — 90 Sekunden

Zwei Lesarten derselben URL

Arbeitet Keycloak als Identity Broker, schickt er Nutzer mit einem AuthnRequest zu einem externen Identity Provider. Zurück kommt eine SAML-Antwort mit einer Assertion, die festhält, wer sich dort angemeldet hat. Wie diese Antwort transportiert wird, regeln die sogenannten Bindings. Beim POST-Binding steckt die Signatur als XML-Signatur im Dokument selbst. Beim HTTP-Redirect-Binding dagegen wird die Nachricht komprimiert, Base64-kodiert und als Parameter SAMLResponse an die URL gehängt, während die Signatur in einem eigenen Parameter Signature daneben steht. Sie gilt laut SAML-Bindings-Spezifikation nicht dem XML, sondern der Zeichenkette SAMLResponse=…&RelayState=…&SigAlg=… aus den URL-kodierten Werten.

Warum das heikel ist, steht in der Spezifikation gleich mit. Die Reihenfolge der Parameter in der URL ist nicht festgelegt, der Empfänger muss die signierte Zeichenkette also selbst wieder zusammensetzen. Und weil es für denselben Wert mehrere gültige URL-Kodierungen gibt, muss er dabei die Originalwerte verwenden, genau so, wie sie angekommen sind. Damit hält jede Implementierung zwei Fassungen derselben Anfrage in der Hand: die rohe für die Signatur und die dekodierte für die Verarbeitung. Das geht gut, solange beide aus denselben Parametern entstehen. Zerlegen zwei Parser die URL aber unterschiedlich, prüft die eine Seite etwas anderes, als die andere verwendet. Dieses Muster heißt Parser-Differential. Es ist eng verwandt mit dem XML Signature Wrapping beim POST-Binding, bei dem Prüfer und Verarbeiter verschiedene Elemente desselben Dokuments betrachten.

Genau hier lag der Fehler. Den Wert nimmt die Methode SAMLEndpoint.redirectBinding über die JAX-RS-Annotation @QueryParam entgegen, wie die Analyse von Ostorlab zeigt. Das Framework dekodiert Parameternamen, bevor es sie abgleicht, und so zählt auch ein prozentkodiert geschriebener Name als SAMLResponse. Stehen beide Schreibweisen in der Anfrage, bekommt die Methode den Wert, der zuerst kommt. Die Signaturprüfung in SamlProtocolUtils.verifyRedirectSignature baut ihre Zeichenkette dagegen aus KeycloakUriInfo.getQueryParameters(false), und dort bleiben die Namen kodiert. Für sie gibt es den kodierten Parameter unter dem Schlüssel SAMLResponse schlicht nicht. Also prüft sie die echte, signierte Antwort, während der Broker eine zweite Antwort einliest, die nie jemand signiert hat.

Eine zweite Schwäche macht die Sache rund. Die Prüfung containsUnencryptedSignature stellt nur fest, dass SigAlg und Signature vorhanden sind, und fragt nicht, ob sie zum verarbeiteten Wert gehören. Die Nachricht gilt deshalb als vollständig signiert. Eine Signatur auf Ebene der Assertion prüft Keycloak in diesem Fall nicht mehr, sofern die Assertion unsigniert ist und „Want Assertions Signed“ ausgeschaltet bleibt.

Neu ist das Problem an dieser Stelle nicht. Schon Keycloak 26.8.1 vom 13. Oktober führte unter den Weaknesses, ohne CVE-Nummer, den Eintrag #53354: Auch dort prüfte das Redirect-Binding die Signatur über eine andere SAMLResponse als die verarbeitete. Phase Two beschreibt diese Variante als Aufspaltung über ein Semikolon als Parametertrenner. Innerhalb von zwei Releases ist CVE-2026-117691 damit die zweite Umgehung im selben Code.

Was der Fix ändert

Der Fix steckt im Commit 0685265 auf dem Hauptzweig, der die mit 26.8.2, 26.6.9 und 26.4.18 ausgelieferte Korrektur nachzieht. Er berührt zwölf Dateien, fünf davon außerhalb der Tests, und seine Commit-Nachricht benennt die Ursache ungewöhnlich offen: Die Signatur wurde über die rohe Query geprüft, die Nachricht aber über @QueryParam gelesen, das Namen dekodiert und das erste Vorkommen nimmt.

Die Korrektur setzt an drei Stellen an. Zuerst gleicht sie die beiden Lesarten an. UriUtils.parseQueryParameters bekommt getrennte Schalter für Namen und Werte, und KeycloakUriInfo.getQueryParameters(false) dekodiert jetzt die Namen, während die Werte roh bleiben. Kodierte und literale Namen landen so unter demselben Schlüssel, und die Javadoc hält ausdrücklich fest, dass beide Sichten für Signaturprüfungen übereinstimmen müssen. Danach lehnt eine neue Prüfung jede Anfrage ab, in der SAMLResponse, SAMLRequest, RelayState, SigAlg oder Signature mehrfach vorkommt, und zwar auch dann, wenn gar keine Signatur verlangt ist. Im Redirect-Binding greift diese Sperre schon in den Grundprüfungen und endet mit einem Fehler 400. Zuletzt dekodiert Keycloak den signierten Wert und verlangt, dass er dem verarbeiteten entspricht. Damit das möglich ist, übergibt SAMLEndpoint der Methode verifySignature jetzt die verarbeitete Nachricht und den RelayState. Geändert sind der Broker-Endpunkt SAMLEndpoint und der IdP-Endpunkt SamlService, das POST- und das Artifact-Binding lesen die Query nicht auf diese Weise.

Am meisten verrät der letzte Schritt. Die ersten beiden schließen Wege, auf denen zwei Parser auseinanderlaufen können, und einen solchen Weg hatte schon 26.8.1 geschlossen. Die dritte Prüfung fragt nicht mehr, wie eine Abweichung entsteht. Sie stellt eine Invariante sicher: Verarbeitet wird nur, was auch signiert wurde. Ich lese daraus, dass die eigentliche Ursache weder das Semikolon noch die Prozentkodierung war. Es war ein Design, in dem Prüfung und Verarbeitung sich ihre Eingabe unabhängig voneinander beschafften.

Vom eigenen IdP-Konto zur fremden Identität

Eine Anmeldung bei Keycloak braucht der Angreifer nicht, darin sind sich Ostorlab und Red Hat Bugzilla einig. Es genügt ein Realm, der einen externen SAML Identity Provider anbindet, dessen Broker-Endpunkt aus dem Netz erreichbar ist und in dessen IdP-Konfiguration „Validate Signature“ ein- und „Want Assertions Signed“ ausgeschaltet ist. Dazu kommt ein eigenes Konto beim Identity Provider, über das der Angreifer eine gültig signierte Antwort im Redirect-Binding erhält. Den Broker-Login startet er selbst, damit diese Antwort zu einer laufenden Sitzung passt. Dass ausgerechnet die Realms betroffen sind, die Signaturen prüfen, hat eine bittere Logik. Wer „Validate Signature“ ausgeschaltet hat, nimmt laut Keycloak-Doku ohnehin unsignierte Nachrichten an und braucht für eine Fälschung gar keine Lücke.

Der Ablauf selbst ist schnell erzählt. Der Angreifer meldet sich mit seinem eigenen Konto beim Identity Provider an und behält die signierte Antwort. Neben sie legt er eine selbst gebaute, unsignierte Antwort mit dem Namen eines anderen föderierten Nutzers, versteckt unter einem kodiert geschriebenen Parameternamen. Keycloak prüft die echte Signatur, findet sie gültig und meldet dann den Nutzer aus der gefälschten Antwort an. Im Log steht danach nichts weiter als eine gewöhnliche Broker-Anmeldung.

Was diese Sitzung wert ist, hängt am Realm. Der Angreifer übernimmt die Identität des Opfers mit allen Rollen, die Keycloak ihm über Mapper oder direkt gegeben hat, und erreicht per Single Sign-on jede Anwendung des Realms. Melden sich Administratoren über denselben SAML-Broker an, endet die Kette bei der Übernahme des Realms. Das Issue fasst das knapp als Broker-Login als beliebiger Nutzer zusammen.

Wirklich betroffen sind also Realms mit SAML-Identity-Brokering über einen Identity Provider, bei dem ein Angreifer an ein Konto kommt. Bei einem offenen Partner- oder Hochschul-IdP kann das jeder Außenstehende sein. Bei einem geschlossenen Unternehmens-IdP ist es jeder Beschäftigte, der sich anschließend als jeder andere Beschäftigte anmelden kann, Administratoren eingeschlossen. Betreiber reiner OIDC-Realms können dagegen aufatmen, und auch Red Hat Single Sign-On 7 ist laut Red Hat nicht betroffen. Der Fix ändert zwar auch den IdP-Endpunkt für SAML-Clients, eine Auswirkung auf diesem Weg beschreiben aber weder Advisory noch Analysen.

CVEBetroffenFixVoraussetzungCVSS
CVE-2026-117691 (GHSA-c85j-3hq2-q6wj)Keycloak vor 26.8.2, Red Hat build of Keycloak vor 26.6.9 bzw. 26.4.1826.8.2 (Community), Red Hat build of Keycloak 26.6.9 und 26.4.18SAML-IdP mit Signaturprüfung, „Want Assertions Signed“ aus, eigenes Konto beim IdP9.1 (kritisch)
#53354, ohne CVE, VorgängerKeycloak vor 26.8.126.8.1wie obennicht bewertet

Bei den Versionen wirken die Quellen zunächst widersprüchlich, doch das klärt sich schnell. Die GitHub-Advisory-Datenbank nennt weder betroffene noch gepatchte Versionen, das Issue trägt die Labels für 26.8.2, 26.6.9 und 26.4.18. Die beiden kleineren Nummern gehören zum Red Hat build of Keycloak, denn in der Community pflegt das Projekt laut endoflife.date nur noch 26.8, und die Zweige 26.6 und 26.4 endeten mit 26.6.4 und 26.4.7. Ostorlab führt 26.8.0 bis 26.8.1 sowie 26.6 und 26.4 als betroffen und ältere Zweige mit derselben Prüfung als ungepatcht.

Im CISA-KEV-Katalog steht die Lücke bis zum 10. November nicht, Angriffe in freier Wildbahn sind nicht bekannt, und einen EPSS-Wert gibt es noch nicht. Beruhigen sollte das trotzdem nicht, denn ein öffentlicher PoC existiert. Er erschien am 3. November, zwei Tage vor dem Fix, noch ohne CVE-Nummer und mit einer Testumgebung für Keycloak 26.8.1. Da 26.8.1 die Semikolon-Variante bereits schließt, ordne ich ihn dieser Lücke zu, und auch CERT Santé meldet laut Rescana einen quelloffenen PoC. Ein zweiter Eintrag, den Exploit-Datenbanken als PoC führen, ist dagegen nur ein Versionsscanner. Zwei Tage lang war die Lücke damit öffentlich beschrieben, ohne dass es ein Update gab.

Keycloak 26.8.2 und die Backports

Der Fix kam am 5. November mit Keycloak 26.8.2, am selben Tag wie das Advisory. Er ist eine reine Codeänderung im Server, du musst also keinen Schalter umlegen, damit er greift. Den Zweig 26.7 pflegt das Projekt laut Phase Two nicht mehr, wer dort steht, wechselt auf 26.8.2. Etwas Verwirrung stiftete der Releasebeitrag auf keycloak.org, der zusätzlich Backports in 26.6.9 und 26.4.18 nennt. Das sind Versionsnummern des Red Hat build of Keycloak, und Red Hat hat beide am 7. November ausgeliefert: Die Errata RHSA-2026:96039 und RHSA-2026:96040 für 26.6.9 sowie RHSA-2026:96037 und RHSA-2026:96038 für 26.4.18 führen CVE-2026-117691 ausdrücklich auf. Community-Builds mit diesen Nummern gibt es nicht, und die gegenteilige Aussage von Phase Two vom Releasetag ist damit überholt. Für das Community-Image führt der Weg also allein über 26.8.2, mit dem Red Hat build kannst du in deinem Zweig bleiben.

Mit dem Update kommt allerdings deutlich mehr als dieser eine Fix. 26.8.2 schließt 33 Sicherheitsprobleme, neun davon im SAML-Code, und Phase Two zählt 14 Breaking Changes. Drei davon treffen Betreiber besonders häufig. Die Admin-REST-API prüft jetzt über den neuen Client-Scope kc-admin-api die Audience, weshalb Service-Accounts, die die Admin-API aufrufen, diesen Scope ausdrücklich brauchen. Der SAML-Broker verlangt eine gültige Bearer-SubjectConfirmation und lehnt Assertions mit ProxyRestriction ab. Und wer IdP-Konten automatisch verknüpfen lässt, braucht dafür jetzt eine verifizierte E-Mail-Adresse. Hinzu kommen eine abgeschaltete Verarbeitung von SAML-1.1-Anfragen und eine Obergrenze für SOAP-Anfragen.

Gefährlich sind dabei vor allem die Änderungen, die nicht laut scheitern. Ein Automatisierungsjob, der über die Admin-API Clients pflegt, bricht nach dem Update ab, und oft merkt das erst, wer auf sein Ergebnis wartet. Ein Identity Provider, der Assertions ohne passende SubjectConfirmation schickt, hat bisher funktioniert und wird jetzt abgewiesen. Beides fällt nur auf Staging zuverlässig auf, mit echten Broker-Anmeldungen über jeden angebundenen IdP und einem Durchlauf aller Jobs, die mit der Admin-API arbeiten. Betreibst du Keycloak über den Operator, aktualisierst du Operator und Server-Image gemeinsam und schaust danach nach, welches Image tatsächlich läuft.

Härtung über den Patch hinaus

Vor den einzelnen Maßnahmen hilft eine Einordnung. Bei diesem Angriff läuft in Keycloak kein fremder Code, und kein ungewöhnlicher Syscall verrät ihn. Keycloak nimmt eine Anfrage an einem öffentlichen Endpunkt entgegen und trifft daraufhin eine falsche Vertrauensentscheidung. Wirksam ist deshalb, was diese Entscheidung an eine zweite, unabhängige Prüfung bindet, was den Eingangskanal für manipulierte Anfragen schließt oder was den Wert einer gefälschten Identität begrenzt. Alles, was den Container selbst härtet, greift hier ins Leere.

Signierte Assertions verlangen

Mit „Want Assertions Signed“ legst du in der IdP-Konfiguration fest, dass Keycloak eine signierte Assertion erwartet. Diese Signatur steckt als XML-Signatur im dekodierten Dokument und wird am XML geprüft, nicht an der Zeichenkette der URL. An dieser Prüfung scheitert eine gefälschte, unsignierte Assertion, egal über welchen Query-Parameter sie hereingekommen ist. Ostorlab nennt die Einstellung ausdrücklich als Schutz, und die Lücke setzt voraus, dass sie ausgeschaltet ist.

Ich halte das für die wichtigste Härtung, weil sie das Prinzip der Lücke umdreht. Aus einer Signatur mit zwei Lesarten werden zwei Signaturen, die verschiedene Parser prüfen. Die Grenze liegt beim Identity Provider, der Assertions auch tatsächlich signieren muss. Sieh dir das in seiner Konfiguration oder an einer aufgezeichneten Antwort an, bevor du den Schalter umlegst, denn sonst scheitert jede Anmeldung. Den Wechsel probierst du deshalb zuerst auf Staging aus, mit einer echten Anmeldung pro IdP.

Redirect-Binding am Ingress schließen

Viele Identity Provider liefern ihre Antworten per POST-Binding aus. Dann braucht der Broker-Endpunkt unter /realms/<realm>/broker/<alias>/endpoint keine GET-Anfragen mit einem Parameter SAMLResponse, und du kannst sie schon vor Keycloak abweisen. Phase Two rät genau dazu, solange ein Zweig keinen Fix hat. In Traefik legst du dafür einen eigenen Router mit höherer Priorität an, der Method, PathRegexp und QueryRegexp kombiniert und solche Anfragen an einen Dienst schickt, der sie ablehnt. Mit dem Muster ^.*$ passt QueryRegexp laut Doku auf jeden Wert eines Parameters.

Damit die Regel hält, was sie verspricht, muss sie Parameternamen dekodiert vergleichen, sonst übersieht sie genau die kodierte Schreibweise, um die es hier geht. Bei Traefik ist das der Fall. Der Matcher für Query und QueryRegexp liest die Parameter laut Quellcode über req.URL.Query() und damit über den Query-Parser der Go-Standardbibliothek, der Namen dekodiert. In einem kurzen Test mit Go 1.24 landeten bei mir %53AMLResponse und sogar ein vollständig kodierter Name unter dem Schlüssel SAMLResponse. Weil die Traefik-Doku dazu schweigt, schickst du nach dem Einrichten trotzdem einmal eine kodierte Anfrage gegen deinen Ingress.

Zwei weitere Punkte gehören dazu. Sperre nur SAMLResponse, denn manche IdPs schicken Logout-Anfragen als SAMLRequest per GET. Und sieh vorher im Access-Log nach, welche Bindings deine IdPs wirklich verwenden. Eine allgemeinere Regel, die kodierte oder doppelte SAML-Parameter abweist, bildet zwar den Fix nach, kann laut Ostorlab aber Clients mit ungewöhnlicher Kodierung stören. Red Hat führt sie auch nicht als unterstützten Workaround.

Zweiter Faktor nach dem Broker-Login

Für jeden Identity Provider kannst du in Keycloak einen „Post login flow“ hinterlegen. Die Doku beschreibt ihn als Flow, der nach jeder Anmeldung über diesen IdP zusätzliche Schritte auslöst, etwa einen zweiten Faktor per OTP. Gegen diese Lücke hilft das, weil die gefälschte Antwort dem Angreifer zwar die Identität liefert, aber nicht den OTP-Generator des Opfers. Eine Sitzung entsteht erst, wenn auch dieser Schritt bestanden ist.

Ein Detail der Doku verdient dabei Aufmerksamkeit. Ein einfacher OTP-Flow fordert Nutzer ohne hinterlegtes OTP auf, es beim nächsten Login einzurichten, und hat das Opfer noch keinen zweiten Faktor, richtet der Angreifer ihn kurzerhand in dessen Namen ein. Das Kapitel zu Authentifizierungs-Flows beschreibt aber ein Muster, das genau das verhindert. Die zweiten Faktoren stehen dort als ALTERNATIVE in einem bedingten Sub-Flow mit „Condition - user configured“, der nur läuft, wenn der Nutzer bereits einen zweiten Faktor hat. Ein zweiter Sub-Flow prüft mit „Condition - sub-flow executed“, ob der erste gelaufen ist, und beendet die Anmeldung andernfalls mit „Deny access“. Setzt man diese Konstruktion als Post login flow ein, was ich aus den beiden Doku-Abschnitten ableite, verlangt sie den vorhandenen zweiten Faktor und lässt keine Einrichtung im Namen des Opfers zu.

Das hat seinen Preis. Nutzer ohne zweiten Faktor kommen über diesen IdP erst wieder herein, wenn sie ihn auf anderem Weg eingerichtet haben, und wer schon beim IdP einen zweiten Faktor nutzt, bestätigt sich künftig doppelt. Für Administratoren und privilegierte Rollen halte ich das für vertretbar. Teste den Flow vor dem Rollout auf Staging, mit je einem Konto mit und ohne zweiten Faktor.

Keine Admin-Rechte über den SAML-Broker

Wie weit eine übernommene Identität reicht, legst du selbst fest. Vergibt ein IdP-Mapper Administrator- oder Realm-Management-Rollen, wird jede Lücke im Broker-Pfad zum Weg in die Realm-Übernahme. Ich leite daraus ab, dass administrative Rollen nicht über Mapper aus IdP-Attributen entstehen sollten und die Anmeldung für die Administration in einen Realm ohne SAML-Brokering gehört. Der Aufwand bleibt überschaubar, denn im Kern geht es um ein paar zusätzliche Konten, die du mit einem eigenen zweiten Faktor absicherst.

Wer signierte Antworten bekommen kann

Ohne Konto beim Identity Provider gibt es keinen Angriff. Red Hat rät deshalb in seinen Hinweisen zur Eindämmung, die Kontoregistrierung bei externen Identity Providern zu prüfen und einzuschränken. Bei einem IdP mit Selbstregistrierung schrumpft der Kreis möglicher Angreifer damit erheblich. Geschlossen ist die Lücke so aber nicht, denn Beschäftigte und Partner mit Konto können die nötige signierte Antwort weiterhin erzeugen. Red Hat sagt selbst, dass diese Schritte nur den Schaden begrenzen.

Was hier nicht hilft

Viele Standard-Härtungen bleiben richtig, laufen gegen diesen Mechanismus aber ins Leere. seccomp mit RuntimeDefault, entzogene Capabilities, runAsNonRoot, allowPrivilegeEscalation: false und readOnlyRootFilesystem zielen auf Code, der im Container Schaden anrichten will, und solchen Code gibt es hier nicht. Für den Pod Security Standard „restricted“, für User Namespaces und für ein minimales Base-Image gilt dasselbe. Auch NetworkPolicies und Egress-Sperren greifen nicht, weil der Angriff als ganz normale eingehende Anfrage an einen Endpunkt kommt, den deine Nutzer erreichen müssen.

Trügerisch ist die Option „Want Assertions Encrypted“. Sie sieht nach Schutz aus, verschlüsselt wird aber mit dem öffentlichen Schlüssel von Keycloak, den jeder aus den Metadaten lesen kann. Ein Angreifer verschlüsselt seine gefälschte Assertion also einfach mit. Verschlüsselung schützt die Vertraulichkeit, über die Herkunft sagt sie nichts. Ebenso wenig bringt es, IdP-Zertifikate zu rotieren, denn der Angreifer braucht keinen Schlüssel, nur eine echte Antwort. Und ein CVE-Gate in der Pipeline hätte die Vorgängervariante #53354 nie gemeldet, weil sie gar keine CVE-Nummer bekam. Wer Keycloak betreibt, liest deshalb auch die Weaknesses in den Release Notes.

Mehr zu Ingress-Regeln, Mandantentrennung und Update-Prozessen findest du in der Serie TYPO3 auf Kubernetes unter IT-Grundschutz.

Erkennung und Prüfung

Ob du betroffen bist, verrät zuerst die Version, also kc.sh --version oder das laufende Image. Danach entscheidet die Konfiguration. Sieh in jedem Realm nach, ob SAML Identity Provider angebunden sind und wie dort „Validate Signature“ und „Want Assertions Signed“ stehen. Ist die Signaturprüfung an und sind signierte Assertions aus, passt der IdP genau in das Profil der Lücke. Fehlt die Signaturprüfung ganz, hast du ein Problem, das mit dieser Lücke nichts zu tun hat.

Schwieriger ist die Frage, ob jemand die Lücke schon genutzt hat. Ostorlab nennt als Hinweise GET-Anfragen an den Broker-Endpunkt, in denen SAML-Parameternamen kodiert geschrieben sind oder doppelt vorkommen. Beides findest du allerdings nur, wenn dein Ingress die vollständige Query protokolliert, und dabei solltest du an den Datenschutz denken, denn eine SAMLResponse enthält personenbezogene Daten. Aussagekräftiger ist der Abgleich mit dem Identity Provider: Eine Broker-Anmeldung in Keycloak, zu der der IdP für denselben Nutzer keine Anmeldung kennt, ist verdächtig. Dafür muss Keycloak die Login-Events speichern, was du unter „Realm settings“ im Reiter „Events“ mit „Save events“ einschaltest. Ein Treffer ist ein Anlass zum Nachsehen, noch kein Beweis, und ein gescheiterter Versuch hinterlässt ohne Query-Logging womöglich gar keine Spur.

Hast du einen Verdacht, sperrst du zuerst das Redirect-Binding am Ingress oder spielst das Update ein. Danach meldest du alle Sitzungen des betroffenen Realms ab, widerrufst die Offline-Tokens und gehst die Admin-Events auf geänderte Rollen, neue Clients und neue Credentials durch. An Events vom Typ „Update Credential“ erkennst du, ob jemand im Namen eines Nutzers einen zweiten Faktor eingerichtet hat. Advisory und Analysen nennen keine IoCs, die Suche nach kodierten Parameternamen leite ich deshalb aus dem Mechanismus ab.

Betreiberempfehlung

Akut handeln solltest du, wenn Keycloak vor 26.8.2 einen externen SAML Identity Provider anbindet, dort „Want Assertions Signed“ ausgeschaltet ist und auch Menschen außerhalb deines engsten Teams Konten bei diesem IdP haben. Spiele dann das Update ein oder schließe bis dahin das Redirect-Binding am Ingress. Signierte Assertions schaltest du ein, sobald feststeht, dass dein IdP sie liefert.

Beobachten genügt, wenn deine Realms ausschließlich OIDC verwenden oder deine SAML-IdPs bereits signierte Assertions schicken, die Keycloak auch verlangt. Ins nächste reguläre Wartungsfenster gehört das Update trotzdem, allein wegen der übrigen 32 Fixes in 26.8.2.

Unabhängig vom Einzelfall gilt, was ich bei jeder Lücke sage: Patches und Updates gehören automatisiert. Schlagen Renovate oder Dependabot neue Keycloak-Images und Operator-Versionen selbstständig als Merge Request vor und testet die Pipeline sie mit echten Broker-Anmeldungen gegen Staging, ist ein Security-Release wie 26.8.2 eine Sache von Stunden statt Wochen. Eine Karenzzeit für Routine-Updates schützt dabei vor kompromittierten Releases, Sicherheitsupdates nimmst du davon aus. Gerade bei einem Release mit 14 Breaking Changes zahlt sich dieser Prozess aus, denn der abgewiesene Service-Account an der Admin-API fällt dann im Test auf und nicht erst in Produktion. Wer dagegen von Hand aktualisiert, sitzt in der Urlaubszeit schnell wochenlang auf einer offenen Lücke im Login und spielt danach ein großes Sammel-Update ein, bei dem niemand mehr sicher sagen kann, welche Änderung welchen Fehler verursacht hat.

Häufige Fragen zu CVE-2026-117691

Ich nutze nur OIDC. Bin ich betroffen?+

Nein. Die Lücke steckt im SAML-Redirect-Binding. Betroffen sind Realms, die einen externen SAML Identity Provider anbinden. Das Update lohnt sich trotzdem wegen der übrigen Fixes.

Reicht 26.6.9 statt 26.8.2?+

Nur beim Red Hat build of Keycloak. Dort enthalten 26.6.9 und 26.4.18 den Fix laut Errata. Community-Builds mit diesen Nummern gibt es nicht, für das Community-Image ist 26.8.2 der einzige Weg.

Hilft es, Assertions verschlüsseln zu lassen?+

Nein. Verschlüsselt wird mit dem öffentlichen Schlüssel von Keycloak, den jeder kennt. Gegen die Lücke hilft die Signatur der Assertion, also die Option „Want Assertions Signed“.

Was tun bei Verdacht auf eine übernommene Sitzung?+

Schließe zuerst das Redirect-Binding oder spiele das Update ein. Danach meldest du alle Sitzungen des Realms ab, widerrufst Offline-Tokens und prüfst Admin-Events und neu eingerichtete Credentials.

Fazit

CVE-2026-117691 ist binnen eines Monats die zweite Lücke in diesem Code-Pfad, und gerade der Vergleich der beiden Fixes ist lehrreich. Der erste schloss eine bestimmte Art, die Query aufzuspalten. Der zweite schließt eine weitere und verlangt obendrein, dass der signierte Wert auch der verarbeitete ist. Diese Lehre reicht weit über Keycloak und SAML hinaus. Wo ein Protokoll eine serialisierte Form signiert, muss die Verarbeitung genau aus den Bytes schöpfen, die geprüft wurden, und nie aus einer zweiten Lesart derselben Eingabe. Ähnliche Fehler entstehen überall dort, wo zwei Komponenten dieselbe Anfrage verschieden zerlegen, wie zuletzt auch der Header-Bypass in Traefik gezeigt hat. Es lohnt sich deshalb, die eigenen Anmeldewege einmal gezielt danach abzusuchen, wo eine Vertrauensentscheidung an einer Stelle fällt und die Daten an einer anderen gelesen werden.

Quellen

Ich prüfe deine Keycloak-Realms auf angreifbare SAML-Anbindungen, härte Broker und Ingress und automatisiere den Rollout von Security-Updates.

Keycloak-Audits für Identity Brokering, Konfiguration signierter Assertions und Post-Login-Flows, Ingress-Regeln mit Traefik und Update-Automatisierung mit Renovate und getesteten Pipelines.

Plattform-Betrieb statt Beratung auf Papier: Ich prüfe, patche und härte deine Infrastruktur laufend.

Über den Autor

Foto von Kai Ole Hartwig.

Kai Ole Hartwig

Freiberuflicher DevSecOps-Berater · OnlyOle Consulting

Programmiert seit 2002 – autodidaktisch gelernt, 2012 mit KO-Web selbständig gemacht. Über 100 Projekte, Fokus auf Security, Performance, Automatisierung und Qualität. Heute freiberuflich: DevSecOps-Beratung, Schulungen und Softwareentwicklung.