当前位置: 首页 > 科技观察

为什么我们需要多个SAMLIDP签名密钥?

时间:2023-03-22 12:36:35 科技观察

SAML是一种使用非常广泛的单点登录协议,如果您运行SAML服务器并与许多其他站点集成,那么您几乎可以肯定使用了不安全的设置。SAML安全性的最大威胁不是奇怪的XML边缘案例或黑客窃取您的签名密钥,而是允许您的用户登录您认为他们无权访问的应用程序的低质量第三方实现。为确保SAML断言仅适用于正确的应用程序,请为每个应用程序或服务提供商使用唯一的签名密钥。这个问题不是SAML独有的,签名的JWT和SSO的其他用途(例如OIDC中的那些)也可能遇到类似的缺乏令牌验证的问题。SAML是如何工作的?在高层次上,SAML是一种使用两个系统之间的浏览器间通信来登录用户的方法,否则这两个系统将无法相互通信。当用户想要登录到他们最喜欢的SaaS时,SaaS应用程序(SP或服务提供商)会向您的IDP发送一些有关登录请求的数据。这包括唯一的请求ID和您尝试访问的原始页面等数据。理论上,身份验证请求可以指定IDP应该返回什么类型的用户名和名称等字段,但实际上这会被忽略。这些请求也可以签名,但大多数时候它实际上会在SP轮换其密钥时破坏一些东西。安全性没有什么好处,因为在任何现代系统中,SAML交换都是通过TLS进行的。一旦您的IDP收到身份验证请求,IDP将验证您是否已登录(可能是密码,可能是客户端证书),然后签署断言。断言是SP将验证并用于记录您的内容。然后您的IDP将此断言发送回SP。SP验证密码签名,验证断言应该发送给特定的SP,并提取相关的用户名和其他字段。现在,你可以看到所有你想要的图片!那个签名密钥听起来很吓人!您的直觉可能是不惜一切代价保护该密钥。密钥值得保护,但对您的SAMLIDP安全性的最大可信威胁不是拥有您的SAML服务器的攻击者。攻击SAML的方法攻击SAML的方法有很多种!虽然唯一的签名密钥可以解决其中的一些问题,但它不是灵丹妙药。观众限制问题这是我在这篇文章中关注的重点,稍后我将更详细地讨论它。不出所料,唯一的签名密钥解决了这类问题。被盗的IDP签名密钥:确实,有权访问您的IDP的人可以获得签名密钥的副本,并以任何人身份登录您与之集成的任何网站。如果那是您关心的威胁,那么仅提供签名预言的硬件支持密钥是正确的防御措施。XML和XML安全库:如果可以,您应该使用内存安全库。也就是说,它对第三方断言验证没有实际影响,如果您使用唯一的签名密钥,您的安全状况也不会改变。XML处理问题XML安全是一种内联签名格式,出现于2000年代初期,当时没有人要求它,而且需要它的人更少。但是随着越来越多的人使用它,问题就出现了。其中包括忽略用户名中的XML注释,签名格式本身忽略影响XML解析器的注释,以及不检查您验证的签名是否确实涵盖了您信任的签名。的所有数据。您可以通过使用唯一的签名密钥来减少这些问题的范围。你只需要关心单个应用程序的内部权限,而不是让用户登录你集成的任何服务(授权与否)。解决方案的核心问题是缺少受众限制验证,换句话说,SP不检查断言是否反对它。SAML的设计理念是您的IDP将只有一个签名密钥,您可以将其分发给与之集成的每个人。考虑到SAML的学术背景,它应该是一个协作协议,组织之间有密切的合作。现代企业SAML忽略了所有这些有趣的特性,因为它们是巨大的安全和配置噩梦。当您的IDP签署断言时,它包含两个供SP验证的字段:SP的实体ID和断言发送到的URL。SP可以默默地忽略这些字段,您对此无能为力。作为负责签名密钥的IDP,您如何保护自己免受不可避免的弱SP攻击?与依赖协议的某些部分相比,处理一堆签名密钥的唯一可扩展方法是强制您的断言仅在一个有效的SP上有效,并且每个SP都有一个唯一签名的密钥。这是可行的,因为几乎每个SAMLSP实现都由三部分组成。他们将从请求中提取用户名,验证断言中的签名,并拒绝无效的断言签名,其他一切都应该被认为是可选的。虽然SP可以忽略你的签名,但它非常容易测试,而且这种事情很容易被漏洞赏金报告者发现。与更深奥的观众限制测试不同,这里不涉及复杂性。你如何管理这么多钥匙?过去,我通过编写一堆Ruby来自动生成相关的XML来处理每个SP的唯一签名密钥,从而为Shibboleth管理了多个密钥。每次我遇到另一个错误处理断言的SP时,我都会感谢为减少我们不得不担心的这个问题所做的努力。在理想情况下,我们不会使用SAML。SAML是一种繁琐的协议,它允许您使用身份验证内联签名创建身份提供者的网状网络,其中XML中的空格决定签名是否有效。但SAML将与OAuth2.0和不完善的OIDC一起保留下来。鉴于SAML是事实上的企业单点登录协议,我们将忽略它。如果您的IDP不支持此功能(见下文),您应该向他们提出功能请求!这是您的IDP应该支持的重要安全控制。如果您的IDP确实支持此功能,请为您的新应用程序发布一个per-sp签名密钥。迁移具有旧证书的应用程序需要大量工作,但如果您有特别敏感的应用程序,则值得这样做。所有SaaSIDP都应该在没有任何用户干预的情况下生成每个应用程序的签名密钥,并且默认情况下,每个SP密钥被大量使用以悄悄地提高与这些提供商签订的每份合同的企业安全性。截至2020年3月,唯一拥有此权限的提供商是AzureAD。自托管IDP应确保他们支持每个SP签名密钥并具有启用此功能的文档。理想情况下,共享签名密钥的配置不太明显,因此管理员默认选择每个SP签名密钥。虽然最终由SSO管理员做出正确的SSO选择,但作为安全行业,我们有责任轻松做出正确的选择。IDP支持多个签名密钥没有实施指南,最佳实践也无济于事。以下是截至2020年3月我测试过的各种主要IDP(包括SaaS和自托管选项)的列表。如果您首选的IDP不在此列表中或输入错误,请联系我们。1.AzureAD-SaaSAAzureAD自动为每个“企业应用程序”生成一个新密钥,并且无法在控制台中的应用程序之间共享证书。您可以手动上传自己的证书和私钥,但这并不容易,我不鼓励这样做,AzureAD应该是所有其他SaaSIDP的模型。2.Shibboleth-Java(self-hosted)你必须写很多XML才能让它工作,如果你花几个小时绞尽脑汁配置SpringXML,你应该没有问题。我已经包括了基本需求。要点是您需要创建单独的签名凭据,将签名凭据包含在安全配置中,然后从单独的SP引用该安全配置。此外,我确实喜欢Shibboleth完全是java,即没有内存损坏!,在您自己的服务器上本地运行,并且具有非常符合标准的方法,减少了受奇怪的XML问题影响的可能性。conf/relying-party.xml的示例配置(Shibboleth文档):.........conf/credentials.xml的示例配置(Shibboleth文档):...。..3.PingOne—SaaS这不是默认的,因为默认情况下,PingOne使用共享签名密钥。有一个单独的证书页面,您可以在其中创建新证书。添加一些内容后,您可以设置每个“SAML”应用程序”被配置为使用唯一签名密钥。4.OneLogin—SaaS这不是默认的,因为默认情况下,OneLogin使用共享签名密钥。您可以尝试在个人SAML配置的设置中更改此密钥,但是新的无法添加密钥。您必须导航到单独的“证书”页面以创建新证书,但一旦这样做,您就可以为每个SP创建唯一的签名密钥。添加“证书”(实际上是签名密钥)后,你可以分配给任意SP。5.Okta—SaaS可以,但是需要在API中修改,Okta对每个SP使用不同的entityID,但是defaultt接下来,使用完全相同的凭据签署声明。无法在Okta控制台中上传自定义私钥或轮换签名凭据。但是,您可以创建一个新的签名密钥并通过两个API调用程序关联与应用程序共享该密钥。6.GSuiteSAML-SaaSGSuite的SAML配置允许您在给定时间拥有两个签名证书,因此您可以轮换过期的签名证书。显然,GSuite可以支持其他证书,但它不支持。7.Auth0-SaaS尽管支持独特的OAuth2.0客户端密码,但Auth0在所有SAML“应用程序”之间共享一个签名证书!也没有轮换SAML签名凭据的选项。鉴于您正在动态配置每个SP,因此没有理由不为每个SP生成签名凭据。8.ADFS——ADFSforMicrosoftWindowsServer(Self-Hosted)WindowsServer2019Edition不支持每个“依赖方”(我们称之为SP)的唯一“签名令牌”。运行一些PowerShell以禁用自动轮换后,您可以手动添加备用证书以进行轮换,但它对其他任何事情都没有用。在每个SP上运行ADFS服务器并在每个服务器上使用单独的签名令牌在技术上是可行的。管理起来会很痛苦,更不用说Windows许可成本了,所以我认为这不是一个好的建议。9.Gluu——自托管Gluu的用户界面不提供任何方法将特定签名身份与SAMLSP相关联,也不可能创建新的签名身份。10.DuoAccessGateway–自托管根据普通SP配置的文档,整个DAG服务器只有一个证书。您可以重新创建证书,但这似乎会影响每个没有唯一密钥选项的SP。11.SimpleSAMLphp——自托管SimpleSAMLphp的IDP支持单个服务提供商的唯一密钥,一旦你知道要查找什么,它就很简单了。在“SP远程元数据”参考中,可以通过signature.certificate和signature.privatekey为每个SP指定一个单独的密钥。虽然它确实很好地支持唯一密钥,但如果可以的话,你最好不要使用这个软件。该项目有一个经典的PHPwebapp漏洞。总结有一些深奥的功能,例如动态ACS(断言消费者服务)URL,以及可能被滥用的功能,例如通过未加密的HTTP提供元数据,但同样,在现代企业SAML中,TLS至关重要。我不信任libxmlsec1库,尤其是libxml2库。这两个C库都非常常用,以至于没有真正的替代品。如果您认为使用Ruby、PHP或PythonSAML库是安全的,那您就错了,它们都依赖于libxmlsec1。尽管C库多年来一直为我们提供良好服务,但在2020年,由于严重的内存损坏问题,它将成为安全隐患。libxml2的漏洞历史可以追溯到2004年(16年前!)。虽然libxmlsec1没有相同的记录历史,但我怀疑这只是由于缺乏必要的报告,而不是真的没有内存安全问题。通过使用相对快速的已知漏洞补丁积极维护这些库,可以在一定程度上减轻这种危险,但如果可以的话,我不会使用这些库。就个人而言,我认为入门门槛对于安全外行来说相当高!您必须与第3方进行有效的SSO集成,并且您必须能够访问私钥(我们不太可能再使用它)或能够更改断言的一部分(如用户名)。大多数IDP都不愿意让您更改字段,因为它们是从您无权访问的中央目录中提取的。即使确实满足所有这些条件,这些漏洞通常也只允许您在现有组织内横向移动,而不是完全以不同的帐户登录。接受来自不同组织的断言实际上是一件非常可怕的事情,因为作为一名国内流离失所者,你无能为力。保护自己免受攻击的最佳方法是测试SP的这种行为。但是,我没有在本文中深入研究,Gluu基于Shibboleth,因此您可以手动设置工作配置,这可能会破坏UI。