Windows截图工具Acropalypse漏洞剖析与开发者安全启示

本文深入分析Windows Snip and Sketch工具中的Acropalypse安全漏洞,探讨API设计缺陷导致的敏感信息泄露问题,揭示开发者中心安全的重要性及Postel法则的现代适用性反思。

Windows Snip and Sketch中的Acropalypse漏洞:开发者中心安全的教训

Acropalypse是最初在Google Pixel手机截图工具中发现的安全漏洞,裁剪图片后原始图像仍可被恢复。由于被裁剪部分可能包含敏感信息,这构成了严重的安全问题。该问题的根源在于Android API默认行为从截断文件变为保留现有内容,导致结果图像文件开头包含裁剪后内容,但原始文件末尾仍然存在。图像查看器会忽略这些数据并正常打开文件,但通过对所用压缩算法的巧妙分析,原始图像可以(部分)被恢复。

在该漏洞公布后不久,有人注意到Windows默认截图工具Snip and Sketch似乎存在相同问题,尽管这是完全不同操作系统上的无关应用程序。作者早在2004年就发现过JPEG缩略图图像的类似问题。当相同漏洞反复出现时,表明软件构建方式存在系统性问题。

有缺陷的API

现代Windows文件保存API存在与Android非常相似的问题:默认情况下不会截断现有文件。这个漏洞甚至更严重,因为与Android不同,Windows没有截断文件的选项。Windows文档在是否需要截断文件以及如何实现所需结果方面最多只能说是含糊不清。

旧版Win32 API保存文件的流程大致是:显示文件选择器→获取用户选择的文件名→打开文件。打开文件时程序员必须指定是否覆盖文件,示例代码通常会覆盖文件。然而新的"更安全"的通用Windows平台(UWP)将文件选择器沙盒化在单独进程中,实现了基于能力的访问控制等巧妙功能。它会按需创建文件并返回句柄,如果所选文件存在,不会覆盖现有内容。

从文档来看,程序员会合理地假设文件将是空的:“该storageFile的文件名、扩展名和位置与用户指定的匹配,但文件没有内容。“除非程序员显式截断文件,否则现有文件内容将被保留。如果写入的数据小于现有文件大小,旧内容将保留,导致StackOverflow上出现困惑的帖子。

FileSavePicker的文档没有提及这个问题,虽然示例代码通过使用隐式截断文件的简单FileIO API避免了漏洞。但更复杂的程序会使用DataWriter,而这些示例不会截断文件,文档也没有指出两种API之间的这种差异。

重新审视Postel法则?

为什么这个缺陷持续如此之久?Android 10于2019年发布,而Windows Snip and Sketch自2018年发布以来似乎就一直存在漏洞。标准实践是遵循Postel法则:“发送时要保守,接收时要宽容”。图像查看器应用程序可以找到有效裁剪图像的结尾,并将原始文件的残留视为可以安全忽略的垃圾。因此,很长时间没有人发现问题,当有人最终发现时,最初也没有认识到这是严重问题。

也许是时候超越Postel法则了。它对于互联网的发展很重要,但现在正在成为负担。拒绝无效输入有助于在问题造成较少损害时更早地识别问题。

下一步?

Acropalypse已在Android(CVE-2023-21036)和Windows Snip and Sketch(CVE-2023-28303)上修复,但它也为未来提供了教训。这个案例研究表明了良好文档的重要性,更重要的是精心设计的API和安全的示例代码。它还表明,解决相同问题的多个程序经常具有相同的漏洞,因此仅仅比较独立实现的结果获得的收益可能比最初预期的要少。

虽然作者没有彻底调查UWP API,但初步观察确实引起了一些担忧。例如,OpenAsync的API功能非常有限。Win32 CreateFile允许在打开前检查现有文件并设置安全参数。CreateFile做了大量工作来确保所有操作原子性执行以避免竞争条件。UWP要求这些相同的步骤分开执行。是否可能隐藏着一些竞争条件?

最后,鉴于有缺陷的API,可以合理预期其他应用程序也存在Acropalypse漏洞。扫描此类问题并非易事,但作者认为可以在Process Monitor中发现这种行为。如果有人编写代码来搜索Process Monitor日志中的此类序列,可能会相当有趣。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计