logo

Mo'rt qulf: SAML autentifikatsiyasini chetlab o'tishning yangi usullari

Zakhar Fedotkin

Zakhar Fedotkin

Tadqiqotchi

@zakfedotkin
Chop etilgan: Chorshanba, 10-dekabr 2025, 12:32 UTCYangilangan: Chorshanba, 21-yanvar 2026, 10:34 UTC

Qisqacha mazmun

Ushbu maqolada Ruby va PHP SAML ekotizimida bir nechta parser darajasidagi nomuvofiqliklardan — jumladan atribut ifloslanishi (attribute pollution), nom fazosi chalkashligi (namespace confusion) va Void Canonicalization deb ataladigan yangi hujumlar sinfidan — foydalanib to'liq autentifikatsiya bypass'iga qanday erishish mumkinligi ko'rsatiladi. Bu texnikalar tajovuzkorga ilovaga mukammal darajada to'g'ri SAML hujjatini taqdim etgan holda XML Signature (raqamli imzo) tekshiruvini butunlay chetlab o'tish imkonini beradi.

Ushbu maqolani chop etish/yuklab olish uchun qulay PDF shaklida olishingiz mumkin. Shuningdek, Black Hat taqdimotining slaydlarini ham yuklab olishingiz mumkin.

Mana, zaif GitLab EE 17.8.4 nusxasiga qarshi hujumning namoyishi:

Annotatsiya

Security Assertion Markup Language (SAML 2.0) — bu ishonchsiz va eskirgan XML texnologiyasi asosida qurilgan murakkab autentifikatsiya standartidir. Ushbu eski asos protokolni qo'llab-quvvatlashni juda qiyinlashtirdi va so'nggi yigirma yil ichida jiddiy zaifliklarning uzluksiz oqimiga sabab bo'ldi.

Ushbu maqolada internetda keng qo'llaniladigan ochiq manbali SAML kutubxonalarida autentifikatsiyani to'liq chetlab o'tishga qodir bir nechta yangi Signature Wrapping (XSW, imzoni o'rash) hujum sinflari taqdim etiladi.

Bundan tashqari, men XML parserlar orasidagi nomuvofiqliklarni aniqlash va tahlil qilish uchun mo'ljallangan ochiq manbali vositalar to'plamini taqdim etaman — bu juda kam talab bilan autentifikatsiya bypass'larini topish imkonini beradi.

SAML zaifliklarining so'nggi kunlardagi o'sishi shuni ko'rsatadiki, xavfsiz autentifikatsiya tasodifan yuzaga kelmaydi. SAML kabi protokollarni xavfsiz saqlash faqat tezkor tuzatishlarni emas, balki butun xavfsizlik hamjamiyatining muvofiqlashtirilgan, doimiy sa'y-harakatlarini talab qiladi.

Xizmat provayderi tomonidan boshlangan SAML oqimi

Service Provider-initiated SAML Flow

Xizmat provayderi (Service Provider, SP) tomonidan boshlangan SAML oqimi (SP-Initiated) — foydalanuvchilarning SAML orqali autentifikatsiyadan o'tishning eng keng tarqalgan usulidir. U foydalanuvchi xizmat provayderi veb-saytidagi himoyalangan resursga kirishga urinishidan boshlanadi. Foydalanuvchi hali autentifikatsiyadan o'tmagani sababli, xizmat provayderi SAML autentifikatsiya so'rovini yaratadi va foydalanuvchini tekshirish uchun Identifikatsiya provayderiga (Identity Provider, IdP) yo'naltiradi.

IdP ushbu so'rovni qabul qiladi, uning haqiqiyligini tekshiradi va so'ngra foydalanuvchi shaxsini tasdiqlovchi raqamli imzolangan Assertion (tasdiq)ni o'z ichiga olgan SAML Response (javob)ni chiqaradi. Ushbu javob foydalanuvchi brauzeri orqali xizmat provayderiga (SP) qaytarib yuboriladi. So'ngra SP raqamli imzoni tekshiradi va Assertion'dan foydalanuvchi ma'lumotlarini (masalan, foydalanuvchi nomi va elektron pochta) ajratib oladi. Agar imzo va ma'lumotlar to'g'ri bo'lsa, kirish huquqi beriladi.

XML imzosini o'rash hujumi (XSW)

Ushbu oqimning umumiy xavfsizligi to'liq SAML Response imzosi qanday tekshirilishiga bog'liq. Ko'plab amalga oshirishlarda imzoni tekshirish va assertionni qayta ishlash alohida modullar yoki hatto turli XML parserlar tomonidan bajariladi. XML Signature Wrapping (XSW) hujumi ushbu komponentlar orasidagi nomuvofiqliklardan foydalanadi.

Odatiy stsenariyda tajovuzkor ishonchli Identifikatsiya provayderi tomonidan imzolangan haqiqiy SAML Response'ni ushlab oladi va o'sha hujjatning ichiga o'zboshimcha foydalanuvchi ma'lumotlarini o'z ichiga olgan yangi zararli Assertion'ni kiritadi. Xizmat provayderi javobni qayta ishlaganda, imzoni tekshirish moduli xabarning haqiqiy qismini to'g'ri tasdiqlaydi, SAML'ni qayta ishlash mantig'i esa xato ravishda tajovuzkor tomonidan kiritilgan Assertion'ni iste'mol qiladi. Natijada tajovuzkorning soxta ma'lumotlari haqiqiy deb qabul qilinadi, bu esa imtiyozlarni oshirishga (privilege escalation) olib keladi.

Juraj Somorovski (Juraj Somorovsky) o'zining "On Breaking SAML: Be Whoever You Want to Be" nomli tadqiqotida buni IdP orqali ro'yxatdan o'tish, man-in-the-middle hujumini amalga oshirish yoki hatto Google dorking yordamida ommaviy ochiq fayllarni qidirish orqali bajarish mumkinligini taklif qiladi. Muammo shundaki, bu katta talabni anglatadi. Ixtiyoriy veb-sayt uchun to'g'ri imzolangan SAML Assertion olish juda qiyin. Identifikatsiya provayderlari ularni deyarli hech qachon oshkor qilmaydi, va hatto agar siz qandaydir tarzda birini ushlab olsangiz ham, ko'pchilik xizmat provayderlari uni faqat bir marta qabul qiladi — shundan so'ng u keshlanadi va rad etiladi.

To'liq autentifikatsiyani chetlab o'tish

methodology

Shunday qilib, biz boshqacha yondashuvni qo'llaymiz. Imzolangan Assertion'ni o'g'irlash yoki qayta ishlatishga urinish o'rniga, biz shunchaki IdP'ning maxfiy kaliti bilan imzolangan boshqa istalgan XML hujjatini qayta ishlatamiz.

Ushbu haqiqiy imzo qo'limizda bo'lgach, biz serverning nuqsonli imzoni tekshirish mantig'idan foydalanib, uni bizning zararli Assertion'imiz aslida imzolangan narsa ekanligiga ishontirishimiz mumkin, garchi bu unday bo'lmasa ham.

Xavfsizlik illyuziyasi

Gareth Heyes bilan bo'lgan oldingi tadqiqotimizda — "SAML roulette: the hacker always wins" — biz Document Type Declaration (DTD)larni qayta ishlashdagi nuqsonlardan keng qo'llaniladigan Ruby-SAML kutubxonasiga qarshi XSW hujumini amalga oshirish uchun qanday foydalanish mumkinligini ko'rsatgan edik. Ushbu muammolarni bartaraf etish uchun ikkita xavfsizlik yamog'i chiqarildi — 1.12.4 va 1.18.0 versiyalari.

Ushbu maqolada men bosqichma-bosqich tuzatishlar yetarli emasligini va XML bilan bog'liq zaifliklarni bartaraf etishga qaratilgan bir necha urinishlarga qaramay tub arxitektura beqaror bo'lib qolayotganini ko'rsatish uchun Ruby-SAML 1.12.4 yamog'ini amaliy misol sifatida ishlataman.

XML xavfsizligining nuqsonli amalga oshirilishi

1.12.4 xavfsizlik yamog'i SAML hujjatida DTD mavjud emasligini va u to'g'ri shakllangan (well-formed) XML hujjati ekanligini ta'minlash uchun ikkita yangi tekshiruvni joriy etdi. Bu bizning dastlabki ekspluatatsiyamizni yo'q qilgan bo'lsa-da, muammoning tub sababini bartaraf etmadi. XML Security kutubxonasi tekshirish jarayonining turli qismlari uchun hamon ikkita alohida XML parseriga — REXML (Ruby uchun XML parseri) va Nokogiri (Ruby uchun XML/HTML parseri) — tayanardi.

SAML spetsifikatsiyasiga ko'ra, Assertion elementi — yoki uning ota-elementlaridan biri — enveloped XML Signature yordamida Signature elementi tomonidan havola qilinishi kerak.

Ruby-SAML amalga oshirilishida REXML ham, Nokogiri ham Signature elementini `"//ds:Signature"` XPath so'rovi yordamida topadi, bu esa hujjatning istalgan joyidagi birinchi imzo hodisasini qaytaradi. Shundan so'ng, REXML'da amalga oshirilgan qo'shimcha mantiq imzoning ota-elementi Assertion ekanligini tekshiradi. Ushbu haddan tashqari ruxsat beruvchi XPath so'rovi ekspluatatsiyaning asosiy komponentiga aylandi.

XML Signature — ikki bosqichli imzolash mexanizmi: imzolangan resursning xesh qiymati (DigestValue) va imzolangan elementga URI havolasi Reference elementi ichida saqlanadi. Ushbu havolalarni o'z ichiga olgan SignedInfo blogi keyin o'zi imzolanadi va natijada olingan Base64 kodlangan imzo SignatureValue elementiga joylashtiriladi. Ruby-SAML amalga oshirilishida DigestValue'ni ajratib olish uchun REXML ishlatiladi, so'ngra u Nokogiri bilan o'zgartirilgan (transform qilingan) xeshlangan element bilan solishtiriladi. Xuddi shunday, REXML tomonidan ajratib olingan SignatureValue Nokogiri tomonidan qayta ishlangan SignedInfo elementiga mos kelishi kutiladi — bu esa nomuvofiq XML ishlov berishga ega ikki xil parser o'rtasida beqaror bog'liqlik yaratadi.

Atribut ifloslanishi

Ishonchli ekspluatatsiya yaratish uchun avvalo XML'ning asosiy xususiyati — nom fazolari (namespaces)ni tushunish muhim. XML nom fazolari element va atribut nomlarini Bir xil manba identifikatorlari (Uniform Resource Identifiers, URI) bilan bog'lash orqali ularni malakalashtirish mexanizmini ta'minlaydi.

Nom fazosi e'lonlari maxsus zaxiralangan atributlar oilasi yordamida aniqlanadi. Bunday atributning nomi yoki aynan xmlns bo'lishi kerak (standart nom fazosini e'lon qilish uchun), yoki **xmlns:** prefiksi bilan boshlanishi kerak (muayyan prefiksga ega nom fazosini aniqlash uchun). Masalan:

<Response xmlns="urn:oasis:names:tc:SAML:2.0:protocol"/>
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">

Ikkala shakl ham to'g'ri va elementlarni bir xil SAML 2.0 Protocol nom fazosi bilan bog'laydi.

Nom fazolari Signature Wrapping hujumlari uchun ideal, chunki ular XML elementlarining XPath so'rovlari orqali qanday aniqlanishiga bevosita ta'sir qiladi. Ko'pchilik SAML kutubxonalari XML'ni tahlil qilish uchun libxml2'ga tayanadi. Ushbu kutubxona ko'plab eski (legacy) g'alati xususiyatlarni meros qilib oladi.

libxml2'ning beqarorligining ajoyib namoyishi Hakimning "Abusing libxml2 quirks to bypass SAML authentication on GitHub Enterprise (CVE-2025-23369)" maqolasida topilgan, u ichki keshlash xatti-harakati kutilmagan XML qayta ishlash natijalari uchun qanday suiiste'mol qilinishi mumkinligini ko'rsatadi. Afsuski, ham Entities, ham Doctype'lar endi 1.12.4 yamog'i tomonidan cheklangani sababli, o'sha muayyan hujum vektori endi amalga oshmaydi — bu bizni parserdagi nomuvofiqliklardan foydalanishning muqobil usullarini izlashga majbur qiladi.

Foydali fikrlardan biri bevosita libxml2'ning xmlGetProp hujjatlaridan kelib chiqadi:

Ushbu funksiya #FIXED yoki standart e'lon qiymatlari uchun DTD atribut e'lonlarida qidiradi.

ESLATMA: Ushbu funksiya nom fazolarini e'tiborga olmaydi. Nom fazosini hisobga oluvchi qayta ishlash uchun xmlGetNsProp yoki xmlGetNoNsProp'dan foydalaning.

Ham Ruby (Nokogiri), ham PHP imzoni tekshirishni assertionni tahlil qilishdan desinxronlashtirishi mumkin bo'lgan libxml2 xatti-harakatlarini namoyon qiladi. Nokogiri'da `node.attribute('ID')` (get_attribute emas) yoki qisqartma `node['ID']` kabi atribut qidiruvlari atribut nom fazolarini e'tiborsiz qoldiradi va faqat sodda nomdan foydalanadi. Bir nechta atribut sodda nom bo'yicha to'qnashganda (masalan, ID va samlp:ID), faqat bittasi qaytariladi va hujjatlar qaysi biri qaytarilishini kafolatlamaydi.

PHP'ning DOM'ida: `DOMNamedNodeMap::getNamedItem` ham atributni faqat sodda nom bo'yicha oladi.

Ushbu noaniqlikni parserlar atributlarni qanday hal qilishida bevosita kuzatish mumkin. Quyidagi ikkita bir xil ko'rinadigan XML fragmentlarini ko'rib chiqaylik:

<samlp:Response ID="1" samlp:ID="2"> # 1
<samlp:Response samlp:ID="2" ID="1"> # 2

Birinchi holatda xmlGetProp chaqiruvi 1 ni qaytaradi, ikkinchi holatda esa 2 ni.

Farq faqat element ichidagi atribut tartibiga bog'liq — bu libxml2'dan meros bo'lib qolgan xatti-harakat. Nom fazosi e'tiborga olinmagani va dublikatlar mavjud bo'lganda qaytariladigan atribut aniqlanmagani sababli, dasturchilar qaysi atribut tanlanishini nazorat qila olmaydi.

libxml2'dan mustaqil ravishda o'zining XML tahlil qilish mantig'ini amalga oshiradigan REXML ham xuddi shu atribut ifloslanishi muammosiga moyil. Ham `attributes['ID']`, ham `get_attribute("ID").value` nom fazosini qayta ishlashga qarab nomuvofiq xatti-harakatni ko'rsatadi.

<Response ID="1" samlp:ID="2">		# 1
<samlp:Response ID="1" samlp:ID="2">	# 2

Birinchi holatda `attributes['ID']` orqali atributga murojaat 1 ni qaytaradi, ikkinchi holatda esa 2 ni. Nom fazosi prefiksi mavjud bo'lganda, REXML'ning ichki qidiruvi atribut nomlarini boshqacha ko'rib chiqadi va bu libxml2'ga nisbatan teskari tanlov tartibiga olib keladi. Ushbu nomuvofiqlik shuni anglatadiki, bir xil XML hujjati turli parserlarda turlicha atribut qiymatlarini hosil qilishi mumkin, bu esa tajovuzkorga qaysi element aslida imzolanganini va qaysi biri qayta ishlanganini boshqarish imkonini beradi:

<samlp:Response ID="attack" samlp:ID="ID">
 <Signature>
	<Reference URI="#ID"/>
 </Signature>
 <samlp:Extensions>
	<Assertion ID="#ID"/>
 </samlp:Extensions>
 <Assertion ID="evil"/>
</samlp:Response>

Hujum ish oqimi

  • Imzoni tekshirish moduli XML Signature'ning nishonini nom fazolarini e'tiborga olmaydigan `"//*[@ID='id']"` XPath so'rovi yordamida topadi
  • Biznes mantig'i so'ngra ildiz elementning identifikatori imzo tomonidan havola qilingan bilan mos kelishini tekshiradi — ID'ni nom fazosidan mustaqil atribut oluvchi (masalan, `element['ID']`, `getNamedItem('ID')` yoki `attributes['ID'])` orqali oladi.

REXML'da DTD'siz nom fazosi chalkashligi

Siz allaqachon bilganingizdek, xmlns — zaxiralangan atribut, xml esa yana bir zaxiralangan prefiksdir. Ikkalasi ham XML spetsifikatsiyasi tomonidan belgilangan va qayta e'lon qilinishi yoki boshqa qiymatlarga bog'lanishi mumkin emas.

Biroq, REXML'da bular ichki tarzda oddiy atribut sifatida ko'rib chiqiladi. Ushbu nozik farq jiddiy zaiflik yaratadi. Nom fazosi e'lonlarini qayta belgilash yoki kiritish orqali tajovuzkor nom fazosini hisobga oluvchi XPath so'rovlarining xatti-harakatini boshqarishi mumkin, bu esa REXML'ni boshqa parserlar — masalan, Nokogiri — to'g'ri e'tiborsiz qoldiradigan elementlarni hal qilishga majburlaydi:

<Signature xml:xmlns='http://www.w3.org/2000/09/xmldsig#'/>

Ushbu texnika teskari yo'nalishda ham ishlaydi va tajovuzkorga hujjatni to'g'ri saqlagan holda haqiqiy Signature elementini REXML'ning `"//ds:Signature"` XPath so'rovidan yashirish imkonini beradi. Elementlarni ehtiyotkorlik bilan ichma-ich joylashtirish va nom fazolarini qayta belgilash orqali Signature tugunini Nokogiri uchun ko'rinadigan, ammo REXML uchun ko'rinmas qilish mumkin bo'ladi:

<Parent xmlns='http://www.w3.org/2000/09/xmldsig#'>
 <Child xml:xmlns='#anything'>
	<Signature/>
 </ Child>
</Parent>

Bu tajovuzkorga imzoni aniqlash mantig'ini bo'lish imkonini beradi va parserni hujjat ichidagi kutilmagan joyda Signature elementini topib, tekshirishga majbur qiladi.

XML sxemasi

Endi REXML va Nokogiri'da ikki xil talqin hosil qiladigan to'g'ri XML hujjatini yaratish imkoniga ega bo'lganimizdan so'ng, keyingi qadam XML sxemasini buzmasdan zararli elementlarni qayerga kiritish mumkinligini aniqlashdir.

XML Schema Definition (XSD) barcha XML kodlangan SAML protokol xabarlarining sintaksisi va semantikasini belgilaydi. Ruby-SAML holatida, amalga oshirilish o'n ikkita XSD fayli bilan birga keladi, jumladan protocol-schema.xsd, ular SAML Response'dagi har bir element uchun tuzilma va cheklovlarni belgilaydi.

Biroq, XML Schema tekshiruvi yolg'iz o'zi zararli kengaytmalarning kiritilishini oldini olmaydi. Aniqlangan barcha kengaytma nuqtalarining to'liq ro'yxati qo'shimcha materiallarda keltirilgan. Ular orasida ikkita element to'g'ri SAML Response ichida Signature elementidan oldin paydo bo'lish asosiy talabiga javob beradi: Extensions elementi va StatusDetail elementi. Men Extensions'dan foydalanaman:

<samlp:Response>
 <samlp:Extensions>
 <Parent xmlns="http://www.w3.org/2000/09/xmldsig#">
  <Child xml:xmlns="#other">
	<Signature>
	<SignedInfo>REAL SIGNATURE</SignedInfo>
	</Signature>
  </Child>
 </Parent>
 </samlp:Extensions>
 <Assertion>
	<Signature>
	<SignedInfo>FAKE SIGNATURE</SignedInfo
	</Signature>
 </Assertion>
</samlp:Response>

Imkonsiz XSW

Ushbu bosqichda biz SignatureValue tekshiruvini muvaffaqiyatli chetlab o'ta olamiz, ammo jarayon noto'g'ri DigestValue bilan muvaffaqiyatsizlikka uchraydi. Buning sababi Nokogiri kanonikalizatsiya (canonicalization) va xesh hisoblashni qanday amalga oshirishida. Xesh hisoblash jarayonida parser xeshni hisoblashdan oldin Signature elementini vaqtincha olib tashlaydi va bu bilan imzoning imzolanayotgan ma'lumotlar tarkibiga kiritilmasligini ta'minlaydi.

Biroq, bizning o'zgartirilgan hujjatimizda soxta Signature elementi Assertion ichida qoladi, ya'ni parser endi allaqachon imzo ma'lumotlarining o'zini o'z ichiga olgan satr ustida xeshni hisoblashga urinadi. Bu rekursiv bog'liqlik yaratadi — xesh o'zining xesh qiymatini o'z ichiga olishi kerak — bunday holatda to'g'ri DigestValue'ga erishish mukammal xesh to'qnashuvini (hash collision) yaratishni talab qiladi.

Void Canonicalization texnikasi

Ushbu ko'rinishda imkonsiz muammoni yechish uchun biz SAML spetsifikatsiyasiga yana bir marta yaqindan qarashimiz kerak. Standartga ko'ra, havola qilingan element xeshlashdan oldin bir yoki bir nechta XML transformatsiyalari orqali qayta ishlanishi kerak. Ushbu transformatsiya bosqichini nishonga olish orqali biz yangi hujum sinfiga — men Void Canonicalization deb ataydigan narsaga — yo'l ochamiz.

Kanonikalizatsiya (canonicalization) atribut tartibi, bo'sh joy, nom fazosi e'lonlari va belgilar kodlashi kabi tafsilotlarni standartlashtirish orqali XML hujjatlarini izchil tarzda ifodalash usulini belgilaydi. Ushbu jarayon ikkita mantiqan bir xil XML hujjati bir xil kanonik bayt oqimini hosil qilishini ta'minlaydi, bu esa ishonchli raqamli imzolar va solishtirishlarga imkon beradi.

Kanonikalizatsiyaning ba'zi jihatlari — masalan, XML izohlari (comments) kiritiladimi yoki chiqarib tashlanadimi — oldingi Signature Wrapping (XSW) hujumlarida allaqachon foydalanilgan (SAMLStorm: Critical Authentication Bypass in xml-crypto and Node.js libraries). Biroq, ushbu ma'lum vektorlardan tashqari, kanonikalizatsiya jarayonining o'zida suiiste'mol qilinishi mumkin bo'lgan chuqurroq cheklovlar mavjud.

Keling, nisbiy URI'larning xavflari haqida ochiq ogohlantiradigan XML Signature tavsiyasiga nazar tashlaylik:

Cheklovlar: nisbiy URI'lar kanonik shaklda ishlamaydi.

Qayta ishlash nisbiy URI'lar mutlaq URI'larga aylantirilgan yangi hujjat yaratishi KERAK (SHOULD), shu tariqa yangi hujjat uchun har qanday **xavfsizlik xavfini** yumshatadi.

Ushbu xatti-harakat imkoniyat yaratadi: agar kanonikalizatsiya jarayoni cheklovga duch kelsa, masalan, hal qilinmagan nisbiy URI, u kanonikalashtirilgan satr o'rniga xato qaytarishi mumkin. Tajovuzkor uchun omadli tomoni shundaki, faqat oz sonli XML parserlar bunday muvaffaqiyatsizliklarni to'g'ri qayta ishlash uchun mo'ljallangan. Ko'pchilik amalga oshirishlar bajarilishni jimgina davom ettiradi va yo'qolgan chiqishni bo'sh yoki "void" kanonik shakl deb hisoblaydi, bu esa xeshga kiritilishi kerak bo'lgan ma'lumotlarni samarali tarzda o'tkazib yuboradi. Ushbu kuchli nomuvofiqlik Void Canonicalization hujum sinfining asosi bo'ladi.

Oltin SAML javobi

Ushbu xatti-harakatni namoyish qilish uchun kanonikalizatsiya zaifligidan foydalanadigan quyidagi SAML Response'ni ko'rib chiqaylik:

<samlp:Response xmlns:ns="1">
 <samlp:Extensions>
 <Parent xmlns="http://www.w3.org/2000/09/xmldsig#">
  <Child xml:xmlns="#other">
	<Signature>
	<SignedInfo>REAL SIGNATURE</SignedInfo>
	</Signature>
  </Child>
 </Parent>
 </samlp:Extensions>
 <Assertion>
	<Signature>
	<SignedInfo>EMPTY STRING DIGEST VALUE</SignedInfo
	</Signature>
 </Assertion>
</samlp:Response>

Bu yerda `xmlns:ns="1"` e'loni nisbiy nom fazosi URI'sini belgilaydi. Bu hamon to'g'ri shakllangan XML hujjati, ammo bu libxml2 kanonikalizatsiyasi jarayonida xatoga sabab bo'ladi.

Xavfsiz tarzda muvaffaqiyatsizlikka uchrash o'rniga, Nokogiri'ning kanonikalizatsiya amalga oshirilishi ushbu xato yuzaga kelganda shunchaki bo'sh satrni qaytaradi. Natijada, keyingi DigestValue hisoblash bo'sh kirish ma'lumotlari ustida bajariladi va bo'sh satrning to'g'ri xeshini hosil qiladi (SHA-256 uchun `47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=`).

Ushbu xatti-harakatdan zararli foydalanuvchi bo'sh satrning SignatureValue'siga kirish huquqiga ega bo'lgan taqdirda ham foydalanish mumkin. Kanonikalashtirilgan SignedInfo'ning xeshi yakuniy SignatureValue'ni hosil qilgani sababli, bo'sh satr uchun oldindan hisoblangan imzoga ega tajovuzkor uni ixtiyoriy SAML Response xabari ustida to'liq to'g'ri imzo yaratish uchun qayta ishlatishi mumkin.

libxml2 kanonikalizatsiya mantig'idan yana bir foydalanish SAML Raider repozitoriyasidagi CVE-2025-25292dan oldingi ekspluatatsiyamda topilishi mumkin. Afsuski, bu to'g'ri shakllangan XML emas va endi ishlatilmaydi.

ruby-saml 1.12.4 va php-saml kutubxonalari kanonikalizatsiya ekspluatatsiyasiga zaif, va boshqa PHP XMLDSig amalga oshirishlari, masalan, Rob Richardsning xmlseclibs kutubxonasi ham ta'sirlangan. Buning aksicha, XMLSec Library va Shibboleth xmlsectool zaif emas.

Bunday "Golden SAML Response"ning (assertion da'volari qanday o'zgartirilishidan qat'i nazar har doim imzo tekshiruvidan o'tadigan xabar) namunasi GitHub Samples papkasida mavjud.

To'g'ri imzoni olish

Hatto zararli foydalanuvchi imzolangan SAML Assertion'ga bevosita kira olmasa ham, bu ommaviy foydalanish mumkin bo'lgan to'g'ri, IdP tomonidan imzolangan XML hujjatlari yo'q degani emas. Bir necha turdagi qonuniy, imzolangan ma'lumotlarni ekspluatatsiya uchun qayta ishlatish mumkin.

Eng oddiy manba — SAML metadata. Afsuski, bu fayllar kamdan-kam imzolanadi, ammo ba'zi hollarda metadata URL'lariga ?sign=true kabi parametrlarni qo'shish orqali imzolangan versiyasini olish mumkin.

Yana bir ishonchli manba — imzolangan xato javobi. SAML spetsifikatsiyasiga ko'ra, Request Abstract Type faqat uchta atributni talab qiladi: ID, Version va IssueInstant. Bular to'g'ri SAML so'rov xabari uchun minimal tuzilmani tashkil qiladi. SAML Core 2.0 Specification'da belgilanganidek:

Agar SAML respondenti so'rovni SAML sintaksisi yoki qayta ishlash qoidalariga ko'ra noto'g'ri deb hisoblasa,

u holda agar u javob bersa, u SAML javob xabarini QAYTARISHI SHART (MUST)

Bu shuni anglatadiki, hatto so'rov noto'g'ri shakllangan yoki sintaktik jihatdan yaroqsiz bo'lganda ham, Identifikatsiya provayderi (IdP) muvaffaqiyatsizlikni bildirish uchun imzolangan xato javobini chiqarishi mumkin. Quyida noto'g'ri AuthnRequest ko'rsatilgan:

<samlp:AuthnRequest
 ID="&#x80;"
 IssueInstant="INVALID"
 Version="INVALID">
</samlp:AuthnRequest>

Agar javob ichidagi aks ettirilgan xato tarkibi kanonikalizatsiya xatosini keltirib chiqarsa, imzolangan xato xabari ham bo'sh imzo manbaiga aylanishi mumkin, natijada xesh bo'sh satr ustida hisoblanadi.

Yakuniy ekspluatatsiya

Nihoyat, Web Services Federation metadata yirik identifikatsiya provayderlari uchun deyarli har doim ommaviy foydalanish mumkin. Ushbu hujjatlar tajovuzkorlarga, hatto XML SAML sxemasiga to'liq mos kelmasa ham, to'g'ri imzo elementlarini olishning qulay va qonuniy usulini taqdim etadi.

Hammasini birlashtirib:

  • Enveloped imzo Extension nuqtasiga kiritilgan holda ajratib olindi
  • Zaxiralangan **xml** atribut nom fazosi e'loni Signature elementini SAML qayta ishlash modulidan yashiradi, lekin uni raqamli imzo uchun saqlab qoladi
  • Soxta imzo tuguni Assertion elementida qoladi, ammo bo'sh satrning Digest qiymatini saqlaydi
  • Nihoyat, Void kanonikalizatsiya xesh cheklovlarini chetlab o'tish uchun qayta ishlanmagan istisno (unhandled exception) tashlaydi

Haqiqiy foydalanish stsenariysi

Ushbu yirik SaaS haqiqiy dunyo stsenariysida, batafsil oshkor qilib bo'lmaydigan holda, biz soxta SAML Response yaratish, yangi hisob yaratish va oxir-oqibat autentifikatsiyani chetlab o'tish uchun Ruby-SAML ekspluatatsiyasidan Gareth Heyes'ning "Splitting the Email Atom: Exploiting Parsers to Bypass Access Controls" tadqiqoti bilan birga foydalandik.

Vositalar

Butun ekspluatatsiya jarayonini avtomatlashtiradigan Burp Suite kengaytmasini GitHubdan yuklab olishingiz mumkin. Ushbu zaifliklar SAML Raider kengaytmasiga ham qo'shiladi — kuzatib boring.

Himoya

Ushbu tadqiqotda tavsiflangan xavflarni yumshatish uchun SAML autentifikatsiya tizimlarini amalga oshirish yoki qo'llab-quvvatlashda quyidagi eng yaxshi amaliyotlar qabul qilinishi kerak:

  • Minimal yoki umuman kengaytma nuqtalarisiz qat'iy XML sxemalaridan foydalaning.
  • Kelajakda faqat imzolangan elementlar qayta ishlash uchun ishlatilishini ta'minlang.
  • Barcha SAML va XML xavfsizlik kutubxonalarini yangilab turing, so'nggi xavfsizlik yamoqlari va versiya yangilanishlarini qo'llang.
  • Elektron pochta domen suffikslarini kirishni boshqarish (access control) shakli sifatida ishlatishdan saqlaning, chunki parser nomuvofiqliklaridan bunday cheklovlarni chetlab o'tish uchun foydalanish mumkin.

Vaqt jadvali

  • 2025-yil 29-aprel — Ruby-SAML 1.12.4 zaifligi haqidagi tafsilotlar kutubxona maintaineri bilan bo'lishildi.
  • 2025-yil 27-avgust — Ruby-SAML va PHP-SAML void canonicalization (libxml2) zaifliklari ularning maintainerlariga oshkor qilindi.
  • 2025-yil 10-oktabr — Rob Richardsning xmlseclibs'idagi libxml2 zaifligi maintainerga xabar qilindi.
  • 2025-yil 8-dekabr — Rob Richardsning xmlseclibs kutubxonasi libxml2 kanonikalizatsiya zaifligini tuzatish uchun 3.1.4 versiyasini chiqardi.
  • 2025-yil 8-dekabr — Ruby-SAML maintainerlari 1.18.0'dan oldingi barcha versiyalarga (shu jumladan 1.12.4) ta'sir qiluvchi CVE-2025-66568 va CVE-2025-66567'ni ko'rib chiquvchi e'lonni chop etdi.
  • 2026-yil 20-yanvar — Okta bizning hisobotimizga javob berib, o'zining imzolash xatti-harakatini o'zgartirish SAML/WS-Fed standartlarini buzishini va muammo xizmat provayderlari tomonidan tegishli yamoqlash orqali hal qilinishi kerakligini tushuntirdi.

Xulosa

Ishonchli autentifikatsiya xavfsizligi qo'llab-quvvatlanmaydigan yoki yomon saqlanadigan kutubxonalarga bog'liq bo'lishi mumkin emas. Keng qamrovli va uzoq muddatli tuzatish mavjud SAML kutubxonalarini sezilarli darajada qayta tuzishni talab qiladi. Bunday o'zgarishlar moslikni buzuvchi muammolarni yoki regressiyalarni keltirib chiqarishi mumkin, ammo ular XML tahlil qilish, imzoni tekshirish va kanonikalizatsiya mantig'ining mustahkamligini ta'minlash uchun zarurdir. Ushbu asosiy qayta ishlovsiz, SAML autentifikatsiyasi deyarli yigirma yildan beri davom etib kelayotgan xuddi shu hujum sinflariga zaif bo'lib qolaveradi.