SAML 在设计上是不安全的 | joonas.fi


安全断言标记语言 (SAML) 是一种用于在各方之间交换身份验证和授权数据的开放标准。SAML 通常用于单点登录 (“使用 Google 登录”、“使用 Twitter 登录”等)。这意味着当您想登录 example.com 时,example.com 可以信任并使用外部身份验证提供程序来为您断言用户的身份。SAML 是关于跨组织边界(网络域)传达这些身份验证和身份详细信息。
虽然 Google支持 SAML用例,但 Google/Facebook 主要使用 OAuth2 来处理这些“使用 Google 登录”一般公共身份验证流程。
 
SAML 用于很多地方,它也可能影响您的安全。
SAML 最近出现了灾难性的漏洞 ,影响非常大。例如,如果我理解正确(我可能理解,因为安全研究人员转发了我的反应)芬兰税务机关,大多数政府服务和健康记录系统都很脆弱,攻击者可能会继续窥探人们的纳税申报表、健康记录以及基本上任何可在线获取的与政府相关的内容。
它在很大程度上被媒体忽略了,也许是因为这些漏洞没有被利用(或者没有检测到这样的实例)。
 
为什么 SAML 不安全?
SAML 使用基于计算值的签名。这种做法本质上是不安全的,因此 SAML 作为设计是不安全的。
 
为什么对计算值进行签名很危险?
总而言之:一旦您将安全性基于某些计算属性,您现在就可以利用此计算中的任何缺陷、差异或歧义。计算越复杂,就越危险。SAML 签名计算非常复杂。
但是让我们继续解释这个概念。让我们拿一个伪身份文件(尽管实际 SAML 是 XML):

$ cat assertion.json
{
  "signed_in_user": "Joonas"
}

我们可以签署上面的文件,就像一堆字节:
$ cat assertion.json | sha1sum
e58dc03a7491f9e5fb2ed664b23d826489c42cc5

现在,如果我们稍微更改文件(我在 {之前添加了空格)。我们注意到签名发生了变化:
$ cat assertion.json
 {
  "signed_in_user": "Joonas"
}
$ cat assertion.json | sha1sum
0bc80a9ee02f611b70319c9fe12b7e504107354a

这是一个非常好的属性,因为理想情况下,我们希望对安全关键文档(SAML 是)的任何更改(即使是那些在 JSON 级别被认为毫无意义的更改)以生成不同的签名。
此属性称为不可延展性
 延展性通用定义
可以在不破碎的情况下塑造成其他东西的东西的质量,例如粘土的延展性。
我们将blob文档签名为原始字节 使得这种不可延展性,即它不能在不破坏它的情况下成形。这是信息安全领域的理想行为。
SAML 具有延展性,因为它的签名基于计算值,
 
为了通过示例进行解释,让我们回到 JSON 示例。我们将使用jq (一个 JSON 转换实用程序)从我们的文档内部计算一些东西:
$ cat assertion.json
 {
  "signed_in_user": "Joonas"
}

$ cat assertion.json | jq .
{
 
"signed_in_user": "Joonas"
}

(jq .意味着只需重新打印整个文档)
注意文件是如何通过管道jq删除空间的?那是因为在 JSON 级别,空间并不重要。乍一看,这似乎并不有趣,但我们正在快速前往 危险区域
让我们对计算值进行签名:
$ cat assertion.json | jq . | sha1sum
e58dc03a7491f9e5fb2ed664b23d826489c42cc5

即使文件仍然有空格修改,签名现在与原始签名匹配(来自没有添加空格的文件)。
为什么这很危险?让我们再次更改文件:
$ cat assertion.json
{
  "signed_in_user": "EvilAttacker",
 
"signed_in_user": "Joonas"
}

$ cat assertion.json | jq . | sha1sum
e58dc03a7491f9e5fb2ed664b23d826489c42cc5

# the above is because:

$ cat assertion.json | jq .
{
 
"signed_in_user": "Joonas"
}

签名仍然与原始文件匹配。这是因为重复键是有效的 JSON,在处理时被删除,并且大多数 JSON 实现让最后一个键获胜。
现在,如果您有两段不同的代码来处理 SAML 文档,并且它们对 JSON 重复键(= 消息语义内容)有不同的解释/解析器行为,会发生什么?
攻击者要求身份提供者为他签署断言,但由于 SAML 的延展性,他能够攻击解析器差异并篡改文档,使其对签名验证仍然有效,但可以访问不同用户的数据。
现在我希望解释了延展性和基于计算/解释内容的签名是多么危险。
 
实践中的 SAML 漏洞
这些 SAML 漏洞发生的事情并不像我们的 JSON 示例那么简单,但这说明了这些漏洞的原理及其根本原因:对计算值和延展性进行签名。
最新的漏洞是由于 XML 往返不稳定性造成的 (请参阅标题“XML 往返漏洞是什么样的”)。
总之,当解析 XML -> 编写 XML 产生语义不同的文档时,就会出现漏洞,即encode(decode(xmlDocument)) != xmlDocument)。
 
....
点击标题

让我们摆脱 SAML。 一些专家似乎推荐 OAuth2 或 OpenID Connect:


如果供应商向您提供 SAML,请寻求替代方案。