时隔16年Jeff Barr重返10.23-25 QCon上海站,带你看透AI如何重塑软件开发! 了解详情
写点什么

前车之鉴:苹果的 GoToFail Bug

  • 2014-03-12
  • 本文字数:2344 字

    阅读完需:约 8 分钟

新近发现的 iOS 和 OS X安全缺陷揭示出编码规范、单元测试、系统测试、代码复查方案、错误管理策略和工具部署方面的缺陷冰山。

ZDNet 的 Larry Seltzer 称这一缺陷“震撼且尴尬”,苹果同时为 iOS 6 发布补丁更是从侧面证实了其严重性。“苹果并不愿意 iOS 用户继续使用 iOS 6 系统,但尽管如此,他们还是修复了缺陷。这足以说明其严重程度。”Larry 说。

到这篇文章完成时,苹果已经为 iOS 和 OS X 发布了软件更新,用以修复该问题:一个能让攻击者拦截、获取并修改加密数据的通信漏洞。但从这个故事中,我们还是能够学到某些东西。

谷歌的Adam Langley 解释说,这一缺陷位于苹果开源发布的SSL/TLS 协议实现—— SecureTransport 框架中,缺陷的引发原因在于部分代码不可达。试看如下代码:

复制代码
static OSStatus
SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams,
uint8_t *signature, UInt16 signatureLen)
{
OSStatus err;
...
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
goto fail;
...
fail:
SSLFreeBuffer(&signedHashes);
SSLFreeBuffer(&hashCtx);
return err;
}

注意其中有两个连续的 goto fail 语句。由于 if 语句没有加大括号,因此执行时,第二处 goto fail 会让程序直接跳转到 fail 标签,从而避开 if 语句之后的验证。这会导致在跳转的那一刻 err 变量不含任何错误信息,方法也无法返回任何。Adam Langley 继续解释道:

签名验证将检查 ServerKeyExchange 消息中的签名。DHE 和 ECDHE 密文族将这一技术用于连接过程中的临时密钥交换。服务器发起请求:“这里是临时密钥和签名,你可以通过我的证书证实我是发起者。”如果这时临时密钥和证书链之间的关联被破坏,所有的验证都会失效。这种情况下虽然仍然可以向客户端发送正确的证书链,但握手过程可能用错误的私钥签名,甚至没有签名!我们无法证实服务器端是否持有与证书中公钥配对的私钥。

诚如 Larry Seltzer 所言,因为苹果没有给出更多细节,我们无从知道这一 bug 是如何被发现的,但这件事让他开始好奇苹果的代码复查实践。他还指出,虽然这个错误一眼就能够发现,但当你面对足有 1970 行长度的整个文件时,将其识别出来就会很难。

Twitter 上#gotofail 主题的很多评论者公然视“使用 goto”为罪魁祸首,最著名的当属 Dijkstra 论文中对 goto“有害”的定性。这点是无可争议的,荷兰代尔夫特理工大学的软件工程教授 Arie van Deursen 试着通过返回错误代码这种惯用法实现一种类似C 中的异常机制来解释goto 的用法,这样一来,那种惯用法就成了罪魁祸首。

Van Deursen 写道,实际上,返回错误代码惯用法普遍存在于含 bug 的文件中,并且本身存在一定的问题。 2005 年 van Deursen 与 Magiel Bruntink,Tom Tourwe 合著论文的主要成果之一就是,通过审查某相当规模的代码库发现“每千行代码中因为 return-error-code 惯用法而导致的缺陷密度达 2.1”。 这么高的缺陷密度的罪魁祸首是未检查调用、未正确传播的返回值以及未正确处理的错误条件导致的,落实了“这一惯用法相当容易出错”的罪名。

苹果前职员 Kevin Marks 在 van Deursen 的跟帖后留言指出,可以使用预处理宏使返回错误代码的方式更安全。这方面的例子包括 BailOSErr 以及致力于实现C 的异常机制方面的工作就是这样用的例子。

说起错误代码的管理,Chris Leishman 在评论van Deursen 观点时称,错误指示变量被初始化为success,这才是两行goto 真正引发漏洞的主要原因。如果错误指示变量的初始化改为OSStatus err = OSUnknownError,系统执行会更安全。

另一方面, Plausible Labs 的软件工程师 Landon Fuller 提供了bug 所影响那部分代码的可测性分析并证实 SSLVerifySignedServerKeyExchange 能够进行隔离性单元测试。 C. Keith Ray 强调了 TDD 的一个观点:“如果你要编写一条 if 语句,那你必须事先准备一个调用这条语句的测试。你需要在条件为真和为假的情况下分别测试”。

Arie van Deursen 指出这一事件还有更多值得争议的地方。

他最先注意到含 bug 的文件“明显不是自动规范化的,其中有大量格式不一的空格、制表符和代码注释”,而“正确的缩进能立刻显示正在发生的可疑事”,并让 bug 查找更容易。除此之外,他进一步建议“将编码格式作为一项安全特性”,而“将空格作为一项安全关注点”。

Langley 在其博客中写道,他认为代码复查是防止这类问题发生的有效手段。但 Arie van Deursen 指出,先前微软有一项代码复查研究曾证实以下观点:

复查并不是像很多项目成员所想的那样,通常情况下都能找出缺陷;而找出深层、微妙或是“宏”层次的问题就更罕见了。也许依靠这种程度的代码复查来保证质量境况堪忧。

最后一点,这种情况下工具也没起到作用,如 Langley 所说,Clang 的 -Wall 参数不会发现两行 goto 和其后的死代码。据 Simon Nicolussi 所言,Clang 提供了能发现该问题的 -Weverything 标识,但 GCC 默认去除了这一标识。这点也为 Peter Nelson ——另一位特定 -Wunreachable-code 参数存在指出者所证实。Van Deursen 指出主要问题在于死代码的删除从根本上讲是一个不可判定问题,这需要完备性和误报间的权衡,也正是因为这一原因,缺省情况下才不含不可达检验。

查看英文原文: Lessons Learned from Apple’s GoToFail Bug


感谢邵思华对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2014-03-12 08:063636

评论

发布
暂无评论
发现更多内容

YashanDB数据库表空间管理与优化

数据库砖家

YashanDB数据库部署与维护详细教程

数据库砖家

YashanDB数据库的安全性分析:保护数据的最佳策略

数据库砖家

YashanDB数据库的安全性分析与最佳实践

数据库砖家

YashanDB数据库备份恢复流程详解及实操

数据库砖家

YashanDB数据库的API设计原则与实例

数据库砖家

YashanDB数据库的安全备份策略及实施步骤

数据库砖家

YashanDB数据库的安全体系与防护措施

数据库砖家

YashanDB数据库的版本升级及数据迁移实战指南

数据库砖家

YashanDB数据库的版本控制与数据审计策略

数据库砖家

YashanDB数据库的备份恢复流程及常见问题

数据库砖家

不到 25MB!端侧 TTS 模型 KittenTTS 开源;Aqua Voice 发布 ASR 模型,专为人机对话设计丨日报

声网

YashanDB数据库的成长历程与技术演变

数据库砖家

YashanDB数据库存储优化及空间管理技巧

数据库砖家

YashanDB数据库错误处理与异常管理策略

数据库砖家

YashanDB数据库的API设计与集成指南

数据库砖家

YashanDB数据库的备份与恢复策略详解

数据库砖家

YashanDB数据库的变更数据捕获技术详解

数据库砖家

YashanDB数据库操作日志的安全管理技巧

数据库砖家

YashanDB数据库的安全加固与防攻击实践

数据库砖家

YashanDB数据库的版本控制与回滚机制详解

数据库砖家

YashanDB数据库的本地与云端部署的利弊分析

数据库砖家

YashanDB数据库备份恢复最佳策略

数据库砖家

YashanDB数据库的安装与配置全攻略

数据库砖家

YashanDB数据库的备份恢复流程及注意事项

数据库砖家

YashanDB数据库的SQL兼容性及优化方法研究

数据库砖家

YashanDB数据库备份恢复自动化流程实操指南

数据库砖家

YashanDB数据库表设计的最佳实践与注意事项

数据库砖家

YashanDB数据库常见故障诊断与快速恢复

数据库砖家

YashanDB数据库的安全性及数据保护措施

数据库砖家

YashanDB数据库备份恢复的流程与注意事项

数据库砖家

前车之鉴:苹果的GoToFail Bug_安全_Sergio De Simone_InfoQ精选文章