在Go的标准库中协调公开XML往返漏洞

2020-12-15 03:07:16

这篇博客文章是Mattermost公开披露的Go编码/ xml中与标记化往返相关的三个严重漏洞的一部分。经过几个月的工作,公开披露才得以完成,其中包括自2020年8月以来与Go安全团队合作以及自本月初以来与受影响的下游项目维护者合作。这些漏洞造成了一些潜在的安全问题,其中之一是完全绕过SAML身份验证。

这些问题不会影响Mattermost客户。有关更多信息,请参见下面的“对最重要的客户没有影响”。

尽管Go安全团队做出了巨大努力,但仍无法修补此博客文章中讨论的漏洞。在可预见的将来,只有三个补丁中的一个要修补(请参阅下面的“更新12/13/2020”)。其余问题的缓解措施将是在Go中添加新模式,以明确表明存在这些漏洞。如果Go的标准库中的某些完整性保证不成立,则这些下游项目很容易受到攻击。在我们确定的关键用例中,这些漏洞的隐含意义构成了重大的安全隐患。如果您维护一个依赖XML完整性的基于Go的项目,我们敦促您仔细阅读这篇文章。

我们不会掉以轻心,这种公开决定并非易事。我们现在这样做的原因有三个:

Go安全团队已确定无法可靠地解决漏洞的根本原因。

Go将在即将发布的主要版本中引入与这些问题相关的公开可见的API更改,这有可能在没有明确公开披露的情况下将漏洞公开。 Go安全小组已同意在进行更改之前将Mattermost协调披露,以最大程度地减少无法从新API中受益的对生态系统各部分的影响。有关详细信息,请参阅“即将进行的更改”部分。

在进行公开披露之前,已经采取了谨慎的步骤将问题私下披露给尽可能多的受影响方。本公开中涉及的所有各方已经合作以确保缓解措施到位且足够。

作为我们安全工作的一部分,我们在Go的encoding / xml中发现了三个可独立利用的漏洞。咨询链接如下:

从标题可以明显看出,这些漏洞密切相关。这三个核心问题都是相同的:恶意复制的XML标记会在通过Go的解码器和编码器实现的往返过程中发生变异。

实际上这是什么意思?如果您的应用程序处理XML,并且在处理XML时解析了至少是前一轮解析和序列化输出的标记,那么您将无法再假定该解析的输出与前一轮的输出匹配。换句话说,通过Go的解码器和编码器传递XML不会保留其语义。

在最坏的情况下,这听起来像是一个非问题或功能错误的来源,但事实却更为严重。有些应用程序绝对需要XML中的语义完整性才能确保安全-一个主要的例子是SAML。

SAML或安全声明标记语言是一种用于Web上单点登录的基于XML的标准方法。它在XML文档中传达用户身份,该XML文档的完整性和真实性通过使用加密签名(一种称为XML-DSig的方案)来保证。由于这些漏洞,基于Go的SAML实现在许多情况下容易受到攻击者的篡改:通过向正确签名的SAML消息注入恶意标记,有可能使它仍然显示为正确签名,但可以更改其语义以传达不同的含义。身份要比原始文件好。

这些XML往返漏洞的实际影响当然会因用例而异,但是在SAML SSO中很容易理解:如果可以将SAML消息更改为说自己不是别人,那么结果就是任意特权升级在SAML服务提供者的范围内,或者在某些情况下甚至可以完成身份验证绕过。

如前所述,尽管Go安全团队付出了巨大的努力,但尚无Go补丁可以合理地解决这些漏洞。这并不意味着所有希望都将丢失:随着这些漏洞的公开披露,我们正在公开采购XML验证库,该库可以用作解决方法。该库及其使用的基本说明可以在github.com/mattermost/xml-roundtrip-validator中找到。

在进行公开披露时,任何漏洞都不会影响Mattermost产品的受支持版本。在披露之前,对Mattermost软件的任何影响已独立解决,并已根据Mattermost的标准披露政策告知客户。目前,Mattermost客户无需采取任何措施。

Mattermost的员工最初在2020年8月28日的内部安全审查中检测到了这些漏洞中的第一个。作为立即响应,Mattermost服务器的唯一受影响的功能(当时仍处于beta测试中的新SAML实施)被立即禁用。该更新于9月3日通过点发布向客户推出。那时Mattermost Cloud尚不可用,因此从未受到影响。

在Mattermost服务器版本从5.20.0到5.26.1(含)的非默认配置中,可以使用受影响的SAML实现。只有同时满足以下所有条件,最重要的部署才容易受到攻击:

该服务器运行的版本介于5.20.0和5.26.1之间,于2020年9月之前发布。这不包括5.25.5及更高版本的扩展支持。

管理员已明确启用设置“使用改进的SAML库(Beta)”。

解决这些漏洞的安全版本的详细信息可以在“最安全更新”页面的标识符MMSA-2020-0030下找到。

自从9月发布点以来,Mattermost产品一直没有受到攻击。我们没有证据表明这个问题曾经被利用过。

我们确定了受Go XML双向漏洞影响的三个主要的开源SAML实现:Dex SAML连接器,github.com/crewjam/saml和github.com/russellhaering/gosaml2。在发布任何详细信息之前,所有三个项目的维护者都被包括在私人禁运披露中。维护人员还可以提前访问github.com/mattermost/xml-roundtrip-validator存储库。

我们还私下与依赖于这些SAML实现的重要应用程序和产品的维护者联系,并向他们提前警告了今天的公开内容,而没有透露技术细节。

了解受影响产品的规模和范围可能有助于理解我们为什么要花这么长的时间来协调这一点。除上述SAML实施的维护者外,我们还与20个公司和项目进行了接触。受影响的产品包括:

如果您发现自己属于我们联系的组织中,我们敦促您立即开始修补。

我们不太可能找到所有受影响的用例,库和产品,甚至可能错过了主要用例。即使您没有收到我们的来信,但怀疑您可能会影响您的encoding / xml的特定用例,请考虑查看您的代码库以了解易受攻击的模式。

Go安全团队正在计划对编码/ xml进行更改,以通过从安全角度弃用现有行为来解决往返漏洞。有望在Go 1.16中使用新的API,该API将允许完全禁用名称空间前缀解析。当前的功能将保持可用,但对于需要往返稳定性的用例,它将不再被视为安全; Go将停止接受与其行为相关的漏洞提交。

Go安全团队在确定encoding / xml包及其数据结构的设计不旨在实现安全往返之后,选择了此路径。新的API使他们可以将开发人员的期望降低到更易于管理的水平,因为可以将最有问题的情况下对往返的支持明确删除。

据Mattermost估计,对于当前受漏洞影响的大多数用例,该新API都不是合理的解决方案。解析和解析名称空间是正确实现SAML的基本要求,即使仅考虑一组有限的实际SAML消息而没有严格的命名空间要求,也不太可能实现安全的实现。

因此,即使Go 1.16可用,我们仍建议受影响的开发人员继续使用github.com/mattermost/xml-roundtrip-validator模块。作为一种长期解决方案,重构代码可能会完全避免对往返编码,但尚不清楚是否在所有情况下都可以进行重构。

我们刚刚从Go团队那里听说,将来的版本中可能还会有其他更改。目前尚不清楚这些更改是否能完全解决Go中的XML验证问题,但我们希望这些问题将在不久的将来在Go中得到全面修补。我们已经获悉,本期将与Go团队进行公开讨论,网址为https://golang.org/issue/43168。

XML双向漏洞的第一个漏洞最初是在2020年8月28日发现的,到8月31日,Mattermost已将根本原因追溯到encoding / xml并联系了Go安全团队。下图显示了从最初发现到公开披露的完整时间表。蓝色圆圈代表Mattermost采取的行动,红色圆圈代表Go安全团队的回应。

Mattermost谨感谢Go安全团队和下游图书馆维护者在响应这些重要问题方面所做的努力和合作。

如果您怀疑在Mattermost产品或开源项目(例如github.com/mattermost/xml-roundtrip-validator模块)中发现了漏洞,请将发现的结果报告给负责人[email protected]。我们要求您不要使用公共GitHub问题来报告安全问题。

如果您对Mattermost的应用程序安全性或本披露中包含的漏洞有一般性疑问,请随时通过[email protected]与我们联系。