
Security Assertion Markup Language (SAML) ist ein offener Standard für den Austausch von Authentifizierungs- und Autorisierungsdaten zwischen Parteien in einem föderierten Identitätssystem. Er ermöglicht Single Sign-on (SSO) über Domänen hinweg. Die Schlüsselkomponenten sind:
In einem typischen SAML-Ablauf leitet der SP den Benutzer zur Authentifizierung an den IdP weiter. Der IdP gibt eine signierte SAML-Antwort zurück, die Assertionen über den Benutzer enthält (z. B. E-Mail, Name). Der SP validiert die Signatur und richtet den Benutzer ein oder meldet ihn an.
CVE-2021-21239 ist eine Schwachstelle zur Umgehung der Signaturvalidierung in der Bibliothek pysaml2 (Versionen <6.5.0), die von Redash <=10.1.0 für SAML-SSO verwendet wird. Im Wesentlichen kann ein Angreifer damit eine SAML-Antwort mit einem beliebigen eingebetteten öffentlichen Schlüssel fälschen, was Benutzerimitation und Privilegieneskalation über Just-in-Time (JIT)-Provisioning ermöglicht.
Die Schwachstelle rührt von der Art und Weise her, wie pysaml2 xmlsec1 zur Verifizierung von SAML-Signaturen aufruft. Xmlsec1 bevorzugt standardmäßig eingebettete öffentliche Schlüssel im <ds:KeyInfo> der SAML-Antwort gegenüber dem konfigurierten IdP-Zertifikat. Ein Angreifer kann eine SAML-Antwort mit einem selbst erzeugten RSA-Schlüsselpaar erstellen, den öffentlichen Schlüssel in <ds:RSAKeyValue> einbetten und die Assertion mit dem privaten Schlüssel signieren. Da pysaml2 xmlsec1 nicht darauf beschränkt, nur das vertrauenswürdige IdP-Zertifikat zu verwenden, wird die gefälschte Signatur als gültig erachtet, sodass sich der Angreifer als beliebiger Benutzer (z. B. Admin) anmelden und höchste Privilegien erlangen kann.
Auf Codeebene liegt die Schwachstelle in sigver.py von pysaml2 (Funktion check_signature). Der xmlsec1-Befehlsliste fehlt die Option --enabled-key-data raw-x509-cert, sodass xmlsec1 nicht vertrauenswürdige eingebettete Schlüssel verwenden kann:
com_list = [
self.xmlsec, '--verify', '--enabled-reference-uris', 'empty,same-doc',
'--pubkey-cert-pem', cert_file_name,
'--id-attr:%s' % id_attr, node_name,
'--node-id', nodeid, '--output', output_file_name, xml_file_name
]
Dies ermöglicht Angriffe, bei denen der Angreifer die E-Mail-Adresse in <saml:NameID> ändert, um sich als beliebiger Benutzer auszugeben, wobei das JIT-Provisioning ausgenutzt wird.
Zum Testen des Exploits wird eine lokale Redash-Instanz (v10.1.0 oder früher) mithilfe von Docker Compose gestartet. Das Setup umfasst die Konfiguration von SAML-SSO mit Googles IdP:
Dieses Setup ermöglicht das Testen der gefälschten SAML-Antwort, die über ein Python-Skript oder Burp Suite gesendet wird, und die Verifizierung der Privilegieneskalation.
Die Schwachstelle entsteht dadurch, dass der xmlsec1-Aufruf von pysaml2 die Verwendung eingebetteter Schlüssel zur Verifizierung erlaubt und so das vertrauenswürdige IdP-Zertifikat umgeht. Ein Angreifer erzeugt ein RSA-Schlüsselpaar, erstellt eine SAML-Antwort mit dem öffentlichen Schlüssel in <ds:RSAKeyValue>, ändert Attribute (z. B. die E-Mail-Adresse zu der des Admins) und signiert die Assertion. Xmlsec1 verifiziert mithilfe des eingebetteten Schlüssels und erachtet sie als gültig.
Der Fix wurde in pysaml2 v6.5.0 (erster Commit vom 17. Januar 2021) in src/saml2/sigver.py umgesetzt. Die xmlsec1-Befehlsliste wurde um --enabled-key-data raw-x509-cert erweitert, wodurch die Verifizierung auf das konfigurierte IdP-Zertifikat beschränkt wird:
com_list = [
self.xmlsec, '--verify', '--enabled-reference-uris', 'empty,same-doc',
'--pubkey-cert-pem', cert_file_name,
'--enabled-key-data', 'raw-x509-cert',
'--id-attr:%s' % id_attr, node_name,
'--node-id', nodeid, '--output', output_file_name, xml_file_name
]
Dies erzwingt die Validierung der Vertrauenskette und verhindert die Verwendung eingebetteter Schlüssel. Redash behob dies durch ein Upgrade von pysaml2 in späteren Versionen (z. B. v11+). Anfällige Versionen verwendeten kein --insecure; der Fehler war die fehlende Einschränkungsoption.
Der Exploit-Code ist in cve-2021-21239.py implementiert. Dieses Python-Skript automatisiert den Prozess der Fälschung einer SAML-Antwort, um CVE-2021-21239 in Redash <=10.1.0 auszunutzen und so über JIT-Provisioning Benutzerimitation und Privilegieneskalation zu ermöglichen. Der Exploit zielt auf den Google-Workspace-SAML-IdP ab, der Angriff wurde jedoch auch mit anderen IdPs (keycloak) getestet. Das Skript führt die folgenden Schritte aus:
email="[email protected]").idpid vom SAML-Login-Endpunkt von Redash ab, sofern sie nicht angegeben wurde, und gewährleistet so die Kompatibilität mit der Konfiguration des Ziels.SAMLResponseTempalte.xml) mit Platzhaltern für E-Mail, Namen, Zeitstempel und Assertion-ID. Dynamische UTC-Zeitstempel werden mit einem Gültigkeitsfenster von 5 Minuten erzeugt, um die Validierung von Redash zu bestehen.xmlsec, um das <saml:Assertion>-Element mit RSA-SHA256 zu signieren und den öffentlichen Schlüssel in <ds:RSAKeyValue> einzubetten, um die Schwachstelle auszunutzen./saml/callback?org_slug=default).Die Ausnutzung von CVE-2021-21239 erforderte die Erstellung einer gefälschten SAML-Antwort, die Redash über JIT-Provisioning akzeptiert. Wichtige Schwierigkeiten und deren Umgehung:
<ds:RSAKeyValue>, signiert mit dem privaten Schlüssel.xmlsec1-Binary funktionierten, aber die Python-Bibliothek xmlsec verursachte Digest-Abweichungen aufgrund von Whitespace-/Kanonisierungsproblemen. Umgangen durch die Serialisierung des XML in eine einzelne Zeile (etree.tostring(..., pretty_print=False)) vor der Signierung.NotOnOrAfter führte zur Ablehnung; umgangen durch die Verwendung dynamischer UTC-Zeitstempel mit 5-minütiger Gültigkeit.SAMLResponse doppelt, was zu Parsing-Fehlern führte; umgangen durch das Senden roher Formulardaten.Diese Herausforderungen verdeutlichen die Notwendigkeit präziser XML-Manipulation und der Einrichtung der Umgebung, um die Schwachstelle effektiv auszunutzen. Der bereitgestellte Exploit-Code demonstriert dies erfolgreich, indem er eine SAML-Antwort fälscht, um Benutzer zu imitieren und Zugriff zu erlangen.