水货CTO入职不到半年犯下低级错误,将公司拖入无底深渊

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"从大公司聘请来的 CTO 太水,犯了个低级错误,事后还故意删除代码隐藏证据。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上周末,黑客组织 DDoSecrets 利用 SQL 注入漏洞,入侵了极右翼社交媒体网站 Gab,并下载了 70 GB 的数据。在 Gab 的开源代码中快速浏览一下就会发现,这个关键漏洞是由公司的首席技术官引入的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"CTO 犯的低级错误,CEO 来买单"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"黑客利用 SQL 注入漏洞从 Gab 的后台数据库中窃取了大约 70GB 的平台用户数据,包含该网站的 4000 多万条帖子,之后将所盗走的 70GB 数据交给了爆料网站 Distributed Denial of Secrets(DDoSecrets)。泄露的数据包含公开 \/ 私人贴文、哈希密码与用户私有讯息,涉及 1.5 万名用户,其中还包括前美国总统特朗普。DDoSecrets 已经将这些数据汇编成了一个名为 GabLeaks 的东西,打算将其提供给特定的记者、社会科学家和研究人员进行进一步分析。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"作为一家初创公司,泄露 70G 数据无疑严重影响了用户权益,这个乱摊子让 Gab 的 CEO 疲于应付。2 月 26 日,最初,CEO 安德鲁·托尔巴(Andrew Torba)在 Gab 网站声明中否认了这一入侵行为,但数据泄露之后他又不得不承认已经发生了入侵行为,并且还称攻击者为“恶魔黑客”。Torba 说,该公司已意识到“该领域存在漏洞,并于上周对其进行了修补。” 并且还将着手进行全面的安全审核,在 2 月 28 日的一份声明中,他表示:“整个公司将全力调查发生的事情,并努力追踪和修补问题。”"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/wechat\/images\/ab\/abbec441d6055d3a3cadfb130172bd90.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","text":"黑客发 Twitter 嘲笑 Gab CEO 被吓坏了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通过查看公司的 git commit 发现,导致关键漏洞的代码变更,是在 2 月份的某个时候从 Fosco Marotto 的账户上进行的,他是一名前 Facebook 软件工程师,11 月成为 Gab 的 CTO。周一,Gab 将此 git commit 从网站上删除,但网络上已有图片保存了关键代码。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/wechat\/images\/97\/97c37ad30f8bdc32e9054777ef7a1ad2.jpeg","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这张图片显示的是 2 月份的软件变更情况,图片来自一家保存提交的快照的网站。提交的内容显示,一名软件开发人员使用 Fosco Marotto 的账户提交了代码,代码中明显存在新手错误,这种错误可能会导致报道中的泄密事件。具体来说,第 23 行删除了“reject”和“filter”的代码,这两个 API 函数实现了防止 SQL 注入攻击的编程实践。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这一习惯允许程序员以安全的方式编写 SQL 查询,以“清理”网站访问者在搜索框和其他 Web 字段中输入的内容,确保所有恶意命令在文本传递到后端服务器之前被清除。取而代之的是,开发人员向包含 find_by_sql 方法的 Rails 函数添加一个调用,该方法直接接受查询字符串中未经清理的输入。Rails 是一套广泛使用的网站开发工具包。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"“如果你知道在 Web 应用中使用 SQL 数据库,那么你将听说过 SQL 注入,而且不难发现 find_by_sql 方法不安全警告。Facebook 的前产品工程师 Dmitry Borodaenko 在一封电子邮件中提醒了我这个问题。“现在还不能 100% 肯定这就是 Gab 数据泄露事件中所使用的漏洞,但是绝对有可能是这样的漏洞,在最近提交的 GitLab 仓库中出现的代码更改被恢复,然后他们就让代码离线了。”具有讽刺意味的是,早在 2012 年,Fosco 就曾警告程序员同行们,要使用参数化查询来防止 SQL 注入漏洞。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"删除不安全的代码,隐藏证据"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Gab 开发的安全代码流程遭到质疑,同时,这家社交媒体网站因从其网站中删除提交而受到批评。批评者称,此举违反了 Affero 通用公共许可证的条款,该许可证控制 Gab 对 Mastodon 的重用(用于托管社交网络平台的开源软件包)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"译注:Affero 通用公共许可证(Affero General Public License,Affero GPL 或 AGPL),是一个广泛被使用的自由软件特许条款,最初由 Affero, Inc 撰写。此特许条款最新版本为第 3 版(v3),2007 年 11 月发布。Affero 通用公众特许条款是改自 GNU 通用公众特许条款,并加入额外条款,其目的是为了 Copyleft 条款应用于在网络上运行的应用程序(如 Web 应用),从而避免有人以应用服务提供商方式逃避 GNU 通用公众特许条款。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上述批评者称,这一删除行为违反了一条规定,即要求复刻(fork)的源代码直接从网站上链接。该要求的目的是提供透明度,让其他开源开发者也能从 Gab 同行的工作中受益。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Gab 长期以来一直在 "},{"type":"link","attrs":{"href":"https:\/\/code.gab.com\/","title":"","type":null},"content":[{"type":"text","text":"https:\/\/code.gab.com\/"}]},{"type":"text","text":" 提供提交内容。然后,在周一,该网站突然删除了所有的提交:包括那些创建并修复了关键 SQL 注入漏洞的提交。取而代之的是,Gab 提供了 Zip 存档文件形式的源代码,该文件由密码“JesusChristIsKingTrumpWonTheElection”(不含双引号)保护。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Mastodon 项目的代表没有立即回复询问他们是否同意批评者的担忧的电子邮件。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"此外,Gab 的 Git 提交还显示出,除了关于安全编码和许可合规的问题外,公司开发者也在努力修复他们脆弱的代码。下图显示了有人使用用户名“developer”尝试完全修复包含 SQL 注入漏洞的代码,但没有成功。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/wechat\/images\/70\/70ed0e78cb849dc48cda5d309bb1a882.jpeg","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"线程参与者对此的反应是讽刺地指出开发者似乎遇到的困难。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/wechat\/images\/b4\/b42f4d262d4d957eb3e479ebb0e630e8.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在 Gab 的安全漏洞事件,前后的代码处理为开发者提供了一个案例研究,说明如何维护站点的安全性和代码透明度。考虑到提交的文件使用了 Gab 的 CTO 的账号,这个教训就显得更有分量了,因为在所有的人当中,他知道的东西应该更多。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"原因是 CTO 太水?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这件事情也引起了开发者的广泛关注,一位从事多年 Rails 开发的网友说:“这是不好的代码,让我感到惊讶的是这是由一位前 Facebook 工程师写的(后来他成了 CTO)。粗略检查就能看出一些错误,比如大型原始 SQL 查询完全可以使用 AREL 或 ActiveRecord 这种更惯用的方式,没有清理用户输入等等。”"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"去年 11 月,Gab 宣布聘请 Fosco Marotto 作为他们的新 CTO。Marotto 曾在 Facebook 工作七年,担任软件工程师,负责后端工具包 Parse 的开发,是 Parse 团队的关键成员,目前该工具包已经开源。同时他还利用业余时间帮助 Gab 开发了免费语音网络浏览器 Dissenter。加入 Gab 后,公司在他们网站的声明中说:“Marotto 有 23 年的行业经验,在后端基础架构上有深厚的知识和见解。这有助于 Gab 迅速发展为新的媒体巨头。”"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"防止 SQL 注入,在 Rails 文档中有明确的示例说明("},{"type":"link","attrs":{"href":"https:\/\/guides.rubyonrails.org\/security.html#sql-injection%EF%BC%89%EF%BC%8C%E7%94%9A%E8%87%B3%E7%A4%BA%E4%BE%8B%E4%B8%8E%E8%AF%A5%E6%8F%90%E4%BA%A4%E4%B8%AD%E6%89%80%E8%AE%A8%E8%AE%BA%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%8C%E5%85%A8%E4%B8%80%E6%A0%B7%EF%BC%8C%E6%89%80%E4%BB%A5%E8%BF%99%E4%B8%AA%E6%8A%80%E6%9C%AF%E5%9C%A8","title":"","type":null},"content":[{"type":"text","text":"https:\/\/guides.rubyonrails.org\/security.html#sql-injection),甚至示例与该提交中所讨论的代码完全一样,所以这个技术在"}]},{"type":"text","text":" Rails 里并不是什么新鲜玩意儿。在 2021 年还能让黑客利用到 SQL 注入漏洞,这很让人不可置信,一位网友在 Reddit 上评论道,“代码将要部署到生产环境中,在合并代码之前难道没有让同行审查吗?如果首席技术官审查了开发人员的代码后还犯这种错误,那么要么 CTO 和工程师都是白痴,要么工程师们在故意欺骗这位白痴。”"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"而且除了这是一种糟糕的实践之外,现有的每一个代码静态分析工具都会告诉你,这样编写 SQL 是一个非常糟糕的做法。CI 管道甚至会直接拒绝代码,拒绝合并代码。也就是说,即使我们的某个开发人员试图忽略了这个明显的安全漏洞,系统本身也能阻止它。因此,Gab 要么根本没有任何 SAST 工具,要么故意选择忽略他们的反馈。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"也有人认为 CTO 不会关注这种细节,CTO 应该专注于战略思维,同时让公司中的一到两位开发人员负责日常工作,针对此类基本问题进行代码审查。大部分企业中,CTO 的确属于高级管理人员,善用高层次、有远见的思维制定战略,并担任企业中非常有影响力的沟通者角色。但这种情况不适合 Gab,因为 Gab 总共才只有 26 名员工,那么 CTO 就应该是该领域内对技术最熟练的人,同时也应该为项目的交付流程负责。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这件事情发生后,Marotto 不仅删除了 Gab 的代码库,连带删除了他之前在 Facebook 里负责的 Parse 工具的安全代码。这个 SQL 注入是个新手级别的错误,Gab 团队原来的代码是正确的,反而是被 CTO 搞砸了,很明显,Gab 没有聘请到正确的人。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"延伸阅读:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/arstechnica.com\/gadgets\/2021\/03\/rookie-coding-mistake-prior-to-gab-hack-came-from-sites-cto\/","title":"","type":null},"content":[{"type":"text","text":"https:\/\/arstechnica.com\/gadgets\/2021\/03\/rookie-coding-mistake-prior-to-gab-hack-came-from-sites-cto\/"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/news.ycombinator.com\/item?id=26319649","title":"","type":null},"content":[{"type":"text","text":"https:\/\/news.ycombinator.com\/item?id=26319649"}]}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章