request-free-img

史上最贵的一行代码:Apple “Goto Fail” 漏洞损失近十亿美元

if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail; // ← 这里多了一个完全相同的goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
goto fail;

问你一个小问题:这几行代码值多少钱?

1块,2角,5块,1分,分文不值!

然而,就是这几行看似毫无技术含量的代码,却在2014年给苹果和全球用户带来了近十亿美元的直接与间接损失,被安全圈永久封为:

“The most expensive one-liner in history”
(史上最贵的一行代码)

事情的来龙去脉

2012年4-5月:灾难的种子被埋下

苹果为了支持即将发布的 iOS 7,正在重构 SecureTransport 库,优化 TLS 握手流程,以兼容更新的协议版本。

一位程序员在修改 SSLVerifySignedServerKeyExchange 函数(负责验证服务器密钥交换签名)时,不知是加班过度疏忽,还是代码合并冲突导致,莫名其妙多出了一行一模一样的 goto fail;

为什么没人发现?

  • 两行完全相同的 goto fail; 在视觉上极难察觉(缩进完全一样)
  • Apple 当时的编译器没有开启 -Wall -Wextra,编译器完全不报警告
  • 单元测试恰好没有覆盖“签名验证失败”分支
  • 代码审查时也被人眼漏掉了

2013年9月19日凌晨1点:带着致命缺陷的 iOS 7.0 正式推送全球

那一行多余的 goto fail; 就这样被装进了全球几亿台 iPhone、iPad、iPod touch 和 Mac 设备里,静静运行了整整17个月,无人知晓。

2014年2月21日:真相大白的那一天

  • 下午2点左右,Google 安全工程师 Adam Langley 在旧金山 Google 办公室,用自己的 MacBook 做 TLS 测试时,突发奇想用假证书尝试连接 apple.com……竟然验证通过了!
  • 下午4:26 分,他发出人类历史上最贵的一条推文:
    “Apple’s SSL bug is real (and easily exploitable on iOS).”
  • 安全圈瞬间炸锅,CloudFlare、Facebook 等公司内部紧急复现,全都成功
  • 当晚8点左右,Apple 内部安全团队确认漏洞,连夜准备仅 3.1 MB 的 iOS 7.0.6 紧急补丁

苹果破天荒地主动公开了问题代码,全球程序员看到那两行一模一样的 goto fail; 时,几乎集体发出:

“……oh my god”

原始漏洞代码(开源后公开)

https://github.com/st3fan/Security-55471/blob/master/libsecurity_ssl/lib/sslKeyExchange.c

史上最贵的一行代码:Apple “Goto Fail” 漏洞损失近十亿美元
史上最贵的一行代码:Apple “Goto Fail” 漏洞损失近十亿美元

最终代价

紧急修复成本 + 全球声誉损失 + 潜在被窃取用户数据价值,业界普遍估算:

至少10亿美元

从此,这行多余的 goto fail; 被永远载入计算机安全史册,成为所有程序员的噩梦与警钟。

提醒我们:代码审查、编译警告、测试覆盖率,一个都不能少。


更多问题探讨,请关注公众号:程序员角