為什么我們需要多個(gè)SAML IDP簽名密鑰?

gejigeji
XML安全性是本世紀(jì)初出現(xiàn)的一種內(nèi)聯(lián)簽名格式,當(dāng)時(shí)沒有人提出要求,需要它的人也更少。但用的人多了,問題就出現(xiàn)了,這些問題包括,忽略用戶名中的XML注釋、簽名格式本身忽略對XML解析器有影響的注釋,以及不檢查你驗(yàn)證的簽名是否實(shí)際覆蓋了你信任的所有數(shù)據(jù)。

SAML是一種目前應(yīng)用非常廣泛的單點(diǎn)登錄協(xié)議,如果你運(yùn)行SAML服務(wù)器并與許多其他站點(diǎn)集成,那么幾乎可以肯定你使用的是不安全的設(shè)置。SAML安全面臨的最大威脅不是怪異的XML邊緣案例或黑客竊取你的簽名密鑰,而是低質(zhì)量的第三方實(shí)現(xiàn),這允許你的用戶登錄到你認(rèn)為他們無法訪問的應(yīng)用程序。要確保SAML斷言只適用于正確的應(yīng)用程序,請為每個(gè)應(yīng)用程序或服務(wù)提供者使用惟一的簽名密鑰。

這個(gè)問題并不是SAML獨(dú)有的,簽名的JWT和其他SSO的使用(比如OIDC中的使用)也可能遇到類似的問題,即缺少令牌驗(yàn)證。

SAML是如何工作的?

從較高的層次上講,SAML是一種登錄用戶的方式,它使用兩個(gè)系統(tǒng)之間的瀏覽器內(nèi)部通信,否則它們之間不能相互通信。當(dāng)用戶想要登錄到他們最喜歡的SaaS時(shí),SaaS應(yīng)用程序(SP或服務(wù)提供商)會(huì)將一些關(guān)于登錄請求的數(shù)據(jù)發(fā)送到你的IDP。這包括諸如惟一請求ID和數(shù)據(jù)(如你試圖訪問的原始頁面)之類的內(nèi)容。理論上,身份驗(yàn)證請求可以指定IDP應(yīng)該返回哪種類型的用戶名和名稱之類的字段,但實(shí)際上這會(huì)被忽略。這些請求也可以簽名,但實(shí)際上在SP旋轉(zhuǎn)其密鑰時(shí),大多數(shù)情況都會(huì)使事情中斷。安全性幾乎沒有好處,因?yàn)樵谌魏维F(xiàn)代系統(tǒng)中,SAML交換都是通過TLS進(jìn)行的。

SAML是一種目前應(yīng)用非常廣泛的單點(diǎn)登錄協(xié)議,如果你運(yùn)行SAML服務(wù)器并與許多其他站點(diǎn)集成,那么幾乎可以肯定你使用的是不安全的設(shè)置。SAML安全面臨的最大威脅不是怪異的XML邊緣案例或黑客竊取你的簽名密鑰,而是低質(zhì)量的第三方實(shí)現(xiàn),這允許你的用戶登錄到你認(rèn)為他們無法訪問的應(yīng)用程序。要確保SAML斷言只適用于正確的應(yīng)用程序,請為每個(gè)應(yīng)用程序或服務(wù)提供者使用惟一的簽名密鑰。

這個(gè)問題并不是SAML獨(dú)有的,簽名的JWT和其他SSO的使用(比如OIDC中的使用)也可能遇到類似的問題,即缺少令牌驗(yàn)證。

SAML是如何工作的?

從較高的層次上講,SAML是一種登錄用戶的方式,它使用兩個(gè)系統(tǒng)之間的瀏覽器內(nèi)部通信,否則它們之間不能相互通信。當(dāng)用戶想要登錄到他們最喜歡的SaaS時(shí),SaaS應(yīng)用程序(SP或服務(wù)提供商)會(huì)將一些關(guān)于登錄請求的數(shù)據(jù)發(fā)送到你的IDP。這包括諸如惟一請求ID和數(shù)據(jù)(如你試圖訪問的原始頁面)之類的內(nèi)容。理論上,身份驗(yàn)證請求可以指定IDP應(yīng)該返回哪種類型的用戶名和名稱之類的字段,但實(shí)際上這會(huì)被忽略。這些請求也可以簽名,但實(shí)際上在SP旋轉(zhuǎn)其密鑰時(shí),大多數(shù)情況都會(huì)使事情中斷。安全性幾乎沒有好處,因?yàn)樵谌魏维F(xiàn)代系統(tǒng)中,SAML交換都是通過TLS進(jìn)行的。

一旦你的IDP接收到身份驗(yàn)證請求,IDP將驗(yàn)證你是否已登錄(可能是密碼、可能是客戶端證書),然后簽署一個(gè)斷言。斷言是SP將驗(yàn)證并用于登錄你的內(nèi)容。然后,你的IDP將此斷言發(fā)送回SP。SP驗(yàn)證密碼簽名,驗(yàn)證該斷言是否應(yīng)該發(fā)送到特定的SP,并提取相關(guān)的用戶名和其他字段?,F(xiàn)在,你可以看所有你想看的圖片了!

那個(gè)簽名秘鑰聽起來很嚇人!你的本能可能是不惜一切代價(jià)保護(hù)該密鑰。密鑰值得保護(hù),但是對你的SAML IDP安全最大的可信威脅不是擁有你的SAML服務(wù)器的攻擊者。

攻擊SAML的方法

攻擊SAML的方法有很多!盡管獨(dú)特的簽名密鑰可以解決其中的一些問題,但這并不是萬能的。

受眾限制問題(Audience restriction issue)

這是我在這篇文章中關(guān)注的問題,稍后我將更詳細(xì)地討論它。不出意料,惟一簽名密鑰解決了這類問題。

IDP簽名密鑰被盜

確實(shí),能夠訪問你的IDP的人可以獲得簽名密鑰的副本,并以任何人的身份登錄到與你集成的任何網(wǎng)站。如果這是你所關(guān)心的威脅,則僅提供簽名預(yù)言的硬件支持的密鑰是正確的防御措施。

XML和XML安全庫

如果可以的話,你應(yīng)該使用一個(gè)內(nèi)存安全的庫。也就是說,這對第三方的斷言驗(yàn)證沒有實(shí)際影響,而且如果使用惟一簽名密鑰,你的安全狀態(tài)也不會(huì)改變。

XML處理問題

XML安全性是本世紀(jì)初出現(xiàn)的一種內(nèi)聯(lián)簽名格式,當(dāng)時(shí)沒有人提出要求,需要它的人也更少。但用的人多了,問題就出現(xiàn)了,這些問題包括,忽略用戶名中的XML注釋、簽名格式本身忽略對XML解析器有影響的注釋,以及不檢查你驗(yàn)證的簽名是否實(shí)際覆蓋了你信任的所有數(shù)據(jù)。

你可以通過使用惟一的簽名密鑰來減小這些問題的影響范圍。你只需要關(guān)心單個(gè)應(yīng)用程序的內(nèi)部權(quán)限,而不是允許用戶登錄任何與你集成的服務(wù)(授權(quán)與否)。

解決方案

核心問題是缺乏受眾限制驗(yàn)證,換句話說,SP沒有檢查斷言是否針對它。SAML的設(shè)計(jì)思想是你的IDP將只有一個(gè)簽名密鑰,你可以將它分發(fā)給與你集成的每個(gè)人??紤]到SAML的學(xué)術(shù)背景,它應(yīng)該是一個(gè)合作協(xié)議,組織之間密切合作?,F(xiàn)代企業(yè)SAML忽略了所有這些有趣的特性,因?yàn)樗鼈兪蔷薮蟮陌踩团渲秘瑝簟?/p>

當(dāng)你的IDP簽署一個(gè)斷言時(shí),它包含兩個(gè)供SP驗(yàn)證的字段:SP的實(shí)體ID和斷言要發(fā)送到的URL。SP可以悄悄地忽略這些字段,而你對此無能為力。

作為負(fù)責(zé)簽名密鑰的IDP,你如何保護(hù)自己免受不可避免的弱SP攻擊?

處理一堆簽名鑰匙

相比依賴協(xié)議的某些部分,唯一可擴(kuò)展的方法是強(qiáng)制你的斷言僅在一個(gè)SP上有效,而且是通過具有唯一簽名每個(gè)SP的密鑰。

之所以可行,是因?yàn)閹缀趺總€(gè)SAML SP實(shí)現(xiàn)都包含三個(gè)部分。他們將從請求中提取用戶名,在斷言中驗(yàn)證簽名,并拒絕無效的斷言簽名,其他所有內(nèi)容都應(yīng)視為可選內(nèi)容。

雖然SP可以忽略你的簽名,但是它的測試超級簡單,而且這種事情很容易被漏洞賞金報(bào)告人員發(fā)現(xiàn)。與更深?yuàn)W的受眾限制測試不同,這里不涉及任何復(fù)雜性。

如何管理這么多密鑰?

過去,我通過編寫一堆Ruby自動(dòng)生成相關(guān)XML來處理每個(gè)SP的唯一簽名密鑰,從而為Shibboleth管理了多個(gè)密鑰。每當(dāng)我遇到另一個(gè)錯(cuò)誤處理斷言的SP時(shí),我都會(huì)感謝為減少這個(gè)我們不得不擔(dān)心的問題而付出的努力。

在理想的情況下,我們不會(huì)使用SAML。 SAML是一種繁瑣的協(xié)議,可讓你創(chuàng)建帶有身份驗(yàn)證內(nèi)聯(lián)簽名的身份提供者的網(wǎng)狀網(wǎng)絡(luò),其中XML中的空格確定簽名是否有效。但是SAML以及OAuth 2.0和不完美的OIDC都將保留下來。鑒于SAML是事實(shí)上的企業(yè)單一登錄協(xié)議,我們將忽略它。

如果你的IDP不支持此功能(請參見下文),則應(yīng)向他們打開功能請求!這是你的IDP應(yīng)該支持的重要安全控制。

如果你的IDP確實(shí)支持這個(gè)功能,為你的新應(yīng)用程序發(fā)出每個(gè)sp的簽名密鑰。使用舊的證書遷移應(yīng)用程序需要做很多工作,但是如果你有特別敏感的應(yīng)用程序,則值得這樣做。

所有SaaS IDP都應(yīng)在沒有任何用戶干預(yù)的情況下生成每個(gè)應(yīng)用程序的簽名密鑰,默認(rèn)情況下,每個(gè)SP密鑰的使用率極高,可以悄悄地提高與這些提供商簽約的每個(gè)企業(yè)的安全性。截至2020年3月,唯一獲得此權(quán)限的提供商是Azure AD。

自托管的IDP應(yīng)確保它們支持按SP的簽名密鑰,并具有啟用此功能的文檔。理想情況下,共享簽名密鑰的配置不太明顯,因此管理員默認(rèn)情況下選擇每個(gè)SP的簽名密鑰。

雖然最終要由SSO管理員做出正確的SSO選擇,但是我們作為安全行業(yè)的責(zé)任是使正確的選擇變得容易。

IDP支持多個(gè)簽名密鑰

沒有實(shí)施指南,最佳做法將無濟(jì)于事。這是截至2020年3月我已測試的各種主要IDP(包括SaaS和自托管選項(xiàng))的列表。如果你的首選IDP不在此列表中或條目不正確,請與我們聯(lián)系。

Azure AD – SaaS

Azure AD自動(dòng)為每個(gè)“企業(yè)應(yīng)用程序”生成一個(gè)新密鑰,并且無法在控制臺(tái)中的應(yīng)用程序之間共享證書。你可以手動(dòng)上傳自己的證書和私鑰,但這并不容易,我也不鼓勵(lì)這樣做,Azure AD應(yīng)該是所有其他SaaS IDP的模型。

Shibboleth - Java(自托管)

你必須編寫大量的XML才能使它工作,如果你花了幾個(gè)小時(shí)絞盡腦汁地研究Spring XML配置,就不會(huì)出現(xiàn)任何問題。我已經(jīng)包括了基本的需求。要點(diǎn)是,你需要?jiǎng)?chuàng)建單獨(dú)的簽名憑據(jù),包括安全配置中的簽名憑據(jù),然后從單獨(dú)的SP引用該安全配置。

另外,我確實(shí)喜歡Shibboleth是全java的狀態(tài),即沒有內(nèi)存損壞!,可以在本地自己的服務(wù)器上運(yùn)行,并且采用非常符合標(biāo)準(zhǔn)的方法,從而降低了被奇怪的XML問題影響的可能性。

conf/relying-party.xml的示例配置(Shibboleth文檔):

conf/credentials.xml的示例配置(Shibboleth文檔):

PingOne—SaaS

這不是默認(rèn)的,因?yàn)樵谀J(rèn)情況下,PingOne使用一個(gè)共享簽名密鑰。有一個(gè)單獨(dú)的證書頁面,你可以在其中創(chuàng)建新的證書。添加一些內(nèi)容后,你可以將每個(gè)SAML“應(yīng)用程序”配置為使用唯一的簽名密鑰。

OneLogin—SaaS

這不是默認(rèn)的,因?yàn)樵谀J(rèn)情況下,OneLogin使用一個(gè)共享簽名密鑰。你可以嘗試在單個(gè)SAML配置的設(shè)置中更改此秘鑰,但不能添加新的秘鑰。你必須導(dǎo)航到單獨(dú)的“證書”頁面以創(chuàng)建新證書,但是一旦完成,就可以為每個(gè)SP創(chuàng)建唯一的簽名密鑰。

一旦添加了“證書”(實(shí)際上是一個(gè)簽名密鑰),就可以將它分配給任意的SP。

Okta—SaaS

是的,但是需要在API中進(jìn)行修改。Okta為每個(gè)SP使用不同的實(shí)體ID,但是默認(rèn)情況下,使用完全相同的憑據(jù)對聲明進(jìn)行簽名。無法在Okta控制臺(tái)中上傳自定義私鑰或旋轉(zhuǎn)簽名憑證。

但是,你可以創(chuàng)建一個(gè)新的簽名密鑰,并通過兩個(gè)API調(diào)用將密鑰與應(yīng)用程序關(guān)聯(lián)。

GSuite SAML - SaaS

GSuite的SAML配置允許你在給定的時(shí)間內(nèi)擁有兩個(gè)簽名證書,這樣你就可以旋轉(zhuǎn)過期的簽名證書。很明顯,GSuite可以支持其他證書,但它不支持。

Auth0——SaaS

盡管支持唯一的OAuth 2.0客戶端機(jī)密,但Auth0在所有SAML“應(yīng)用程序”之間共享一個(gè)簽名證書!也沒有選擇旋轉(zhuǎn)你的SAML簽名憑據(jù)。鑒于你正在動(dòng)態(tài)配置每個(gè)SP,因此沒有理由不生成每個(gè)SP的簽名憑據(jù)。

ADFS - Microsoft Windows Server(自托管)

Windows Server 2019版的ADFS不支持每個(gè)“依賴方”(我們稱之為SP)的唯一“簽名令牌”。在運(yùn)行一些PowerShell以禁用自動(dòng)旋轉(zhuǎn)之后,你可以手動(dòng)添加一個(gè)用于旋轉(zhuǎn)的備用證書,但它對其他任何東西都沒有用處。

在每個(gè)SP上運(yùn)行一個(gè)ADFS服務(wù)器并在每個(gè)服務(wù)器上使用單獨(dú)的簽名令牌在技術(shù)上是可行的。這將是痛苦的管理,更不用說Windows許可成本,所以我不認(rèn)為這是一個(gè)好的建議。

Gluu——自托管

Gluu的用戶界面未提供任何將特定簽名身份與SAML SP相關(guān)聯(lián)的方法,也無法創(chuàng)建新的簽名身份。

Duo Access Gateway –自托管

根據(jù)通用SP配置的文檔,整個(gè)DAG服務(wù)器只有一個(gè)證書。你可以重新創(chuàng)建證書,但這似乎會(huì)影響到?jīng)]有唯一密鑰選項(xiàng)的每個(gè)SP。

SimpleSAMLphp—自托管

SimpleSAMLphp的IDP支持單個(gè)服務(wù)提供者的唯一密鑰,一旦你知道要查找什么,它就很簡單了。在“SP遠(yuǎn)程元數(shù)據(jù)”參考中,通過signature.certificate和signature.privatekey可以為每個(gè)SP指定一個(gè)單獨(dú)的密鑰。

雖然它確實(shí)很好地支持惟一秘鑰,但如果可以的話,你最好不要使用這個(gè)軟件。該項(xiàng)目有一個(gè)經(jīng)典的PHP webapp漏洞。

總結(jié)

1. 有一些深?yuàn)W的功能,例如動(dòng)態(tài)ACS(斷言消費(fèi)者服務(wù))URL,還有可能會(huì)被誤用的功能,例如通過未加密的HTTP提供元數(shù)據(jù),但是同樣,在現(xiàn)代公司SAML中,TLS至關(guān)重要。

2. 我不相信libxmlsec1庫,尤其是libxml2庫。這兩個(gè)C庫都非常常用,沒有真正的替代方法。如果你認(rèn)為使用Ruby,PHP或Python SAML庫是安全的,那么你就錯(cuò)了,它們都依賴于libxmlsec1。

3. 盡管C庫為我們服務(wù)了很多年,但到2020年,由于內(nèi)存損壞問題嚴(yán)重,它將成為安全負(fù)擔(dān)。libxml2的漏洞歷史可以追溯到2004年(16年前!)。雖然libxmlsec1沒有相同的記錄歷史,但我懷疑只是由于缺少必要的報(bào)告,而不是真的沒有內(nèi)存安全問題。通過對已知漏洞進(jìn)行相對快速的修補(bǔ)來積極地維護(hù)這些庫,可以在一定程度上緩解這種危險(xiǎn),但是如果可以的話,我不會(huì)使用這些庫。

4. 就我個(gè)人而言,我認(rèn)為對于安全界的外行來說,進(jìn)入的門檻是相當(dāng)高的!你必須與第三方進(jìn)行有效的SSO集成,并且必須能夠訪問私鑰(我們已經(jīng)不太可能使用它了)或能夠更改部分?jǐn)嘌裕ㄈ缬脩裘?。大多?shù)IDP都不愿意讓你更改字段,因?yàn)樗鼈兪菑哪銦o權(quán)訪問的中央目錄中提取的。即使確實(shí)滿足所有這些條件,這些漏洞通常也只能讓你在現(xiàn)有組織中橫向移動(dòng),而不能完全以其他帳戶身份登錄。

5. 接受不同組織的斷言實(shí)際上是一件非??膳碌氖虑?,因?yàn)樽鳛镮DP,你幾乎無能為力。保護(hù)自己不受攻擊的最好方法是測試SP是否有這種行為。不過,我在本文中沒有深入探討這個(gè)問題,

6. Gluu是基于Shibboleth的,因此你可以手動(dòng)設(shè)置一個(gè)工作配置,這可能會(huì)破壞UI。

THEEND

最新評論(評論僅代表用戶觀點(diǎn))

更多
暫無評論