C++ 复杂、内存漏洞,2019 年的软件开发并不安全!

发表于:2019-1-31 09:52

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:AI先锋号    来源:今日头条

  在这篇文章中,本文作者会分享自己过去一年中对软件设计和开发现状的一些观察,并试图在 2019 年为自己找到一个有意义的努力方向。
  在过去 7 年半的时间里,我主要从事客户端软件安全性相关工作,本文的观点主要源于这样的工作背景。我不局限在自己的工作领域,我会从行业的角度来探讨更为广泛的趋势。
  我希望这篇文章对各种从事安全相关工作的人员都有用:不仅是工程师,还包括用户体验设计师和研究人员、项目经理、产品经理、业务经理以及运营人员。无论如何,所有成功之路都需要所有这些人的帮助。此外,本文提供了很多有用的链接供读者参考。
  硬件、软件、平台和生态系统通常过于复杂,我们的许多安全、隐私和滥用问题都源于此。
  01
  好的方面
  加密 Web 正在逐渐盛行!此外,将非安全 Web 标记为不安全,并将安全网站标记为中立的举措正在推行。我们已经对此迅速地进行了改进,且带来巨大的改变,这让我非常震惊。一如既往地感谢 Let's Encrypt,以及其他朝着类似方向努力的浏览器
  虽然内存漏洞仍然普遍存在,但 iOS、Chrome OS 以及 Chrome 都已进行了一些有效的设计(权限降低)和不合理的改进工作(实际上可以进行权限减少工作,寻找 Bug,修复 Bug 和快速部署)。如今,内存损坏的几率要比20世纪90年代或21世纪初低得多。
  iOS 的普及率越来越高,即便这完全是用户自发的,这也是人们认识到新鲜事物价值的标志。当然,人们不太可能在安全本身的基础上做出选择。但安全和隐私是 iOS 核心价值的关键部分,我认为肯定有客户会在意这一点。
  
  内存安全的编程语言占主导地位。此外,增长最快的语言具备内存安全的特性。一些流行的语言甚至是类型安全。(有些人可能会认为类型安全仅仅是额外福利,但对我来说,typefulness 是软件可靠和安全的关键组成部分)。系统软件也有好消息,此前不安全的 Go 和 Rust 正在改善。虽然 Midori 缺点不少,但它仍然可以教给我们广泛适用的深刻教训。
  内存标记是硬件的一种新功能,可以帮助我们解决内存安全问题。人们正致力于在现代系统上实现它。我不认为它是以系统级方式修复 Bug 的替代品,但它在提高安全性方面拥有巨大潜力。
  静态检查程序、编译器和动态检查程序(例如 Address Sanitizer 和其他 LLVM )在过去20年中取得了很大进展。曾经的前沿研究如今变成免费提供的编译器。这太棒了!(在 Clang 或 GCC 中加上 -Wall -Werror,我更喜欢使用 -Weverything -Werror -Wno -padded 等扩展)
  Chrome正在对扩展平台进行一些结构性改进,这应该可以减少我们在该生态系统中看到的一些最严重的滥用行为。
  软件行业正在发生道德和伦理上的觉醒:
  谷歌员工因公司区别对待女性的行为而举行罢工活动;
  Google 取消和五角大楼合作的 Maven 项目;
  反对亚马逊的“Rekognition”的面部识别工具;
  微软员工抗议人工智能战;
  Time Well Spent;
  谷歌放弃 Dragonfly 计划。
  对待安全性问题,我们这一代的工程师正在超越“我能建造它,我做到了,后果是什么?”的心态。前几代人必须做出非常相似的选择。
  (我十分同意所有这些立场,我不会在为战争设计的机器上工作,也不会在 Big Brotherly 审查过的搜索引擎上工作。我愿意为每个人提供平等和公平的待遇而努力。罢工事件是一个好的开始。还接下来还有很长的路要走。)
  对 U2F 的认识和采用的日益增加是一个好消息。(U2F 已被标准化为WebAuthn,它比大多数安全人员预想的复杂得多。)它提供的反网络钓鱼功能至少与 HTTPS 提供的保护一样重要。网络钓鱼和帐户接管一直是我们最大的问题之一,WebAuthn 可以对它们产生很大的影响。基于它,你现在才可以安全访问谷歌、Facebook、Twitter、Dropbox、login.gov 等网站。
  02
  不好的方面
  C++ 仍然及其复杂且非常不安全:
  在 C++ 日益复杂的问题上,C++ 的创建者发现自己处于社区的另一端。Stroustrup 正确地将 C++ 日益增加的复杂性视为该语言的潜在致命风险。
  新的安全 API 并不安全。 - CC++ 编译器继续利用未定义的行为,这是不应存在的行为。(John Regehr:“从开发人员的角度来看,一个非常聪明地识别并默默地摧毁 Type 3函数的编译器变得非常邪恶。”)
  C++ 非常复杂,以至于编程专家都无法找到一种通用的方法来查找静态数组的大小。
  我不可能选择并链接到无限错误报告的列表,其根本原因是内存不安全。一个有趣的练习是浏览一个很好的漏洞记录来源(Project Zero 是我最爱的博客之一),并计算应用程序中有多少 bug。
  当然,如果你发现应用程序存在 bug 或者更多的内存安全漏洞,那也可能是源于研究人员的偏见。但内存损坏 bug 数量众多且经常出现,我觉得这是很大的问题。
  设计一种能够实现所有内存安全性、高性能和良好可用性的语言仍然非常困难。Rust 编译器能够发现并拒绝 C 和 C++编译器没有或无法发现又或者有目的地接受的安全错误。这是 Rust 的功劳,但这门学科非常难以学习。
  在编程语言研究社区中,首先需要证明程序是安全的。这项工作逐渐渗透到人们真正可以用来发送真实软件的语言中。使用学术工具的困难部分是他们的小观众的自然结果,但是一些困难是不可避免的:安全证明意味着你需要真正去证明,这就像人们获得博士学位一样困难。最终,软件工程社区将不得不逐渐且越来越多地致力于满足这一标准。
  显然,2018年很多人都熟知了 Spectre&Meltdown、Foreshadow、L1TF 以及微架构侧通道等概念。共享资源比比皆是。当然,安全问题(通常是由于可怕的复杂性)已经出现了很长一段时间。虽然这些链接主要涉及英特尔架构系统,但没有理由认为 ARM 本质上更安全。特别是,微架构侧通道问题是设计最大性能的自然结果,几乎每个芯片设计师都在尝试这样做,因为这几乎是每个客户都想要的。
  03
  不祥的方面
  滥用(恶意使用合法功能)以比漏洞攻击更多的方式影响更多人的生活。虽然黑客可能会带来令人意想不到的影响,例如以政治影响或大规模数据泄露的形式出现,但是你的朋友和家人感到悲伤的原因更加平淡,而且难以解决:
  电话诈骗、技术支持骗局;加密货币骗局和敲诈勒索。
  恶意软件、crapware 或人们故意安装的“不需要的软件”。(这些通常列在合法商店中,随硬件的设备驱动程序一起提供,或与边缘软件捆绑在一起。)
  spouseware 和 stalkerware。
  正如预言的那样,工作证明无法继续工作。未来几十年将带来越来越多的“挑战”,并且所有计算系统都必须相对于所有成本的总和来证明其价值,包括碳和电子废物。我们将无法再将这些视为外部因素。工作证明系统将继续无法显示足够的成本价值,甚至可能成为监管的重点照顾对象。
  Web 性能的危机也是类似的情况:巨大的浪费,而不是自限的。在过去,我不得不说,即使性能有限,安全性也是可以承受的。通过减少明显的扩展并实现不那么明显的优化,可以获得性能和安全性,现在可以实现。根本原因与现在一样:太多开发人员不使用与用户群相同的客户端系统,他们不知道他们所承担的网络、内存和 CPU 成本。以前,很难看到这些成本。现在,每个浏览器都有一个非常好的 Dev Tools 控制台,没有理由不使用它。
  像 NPM、CPAN 等依赖系统继续让我感到厌恶。它们可能比手动依赖管理更危险,尽管这种做法存在巨大风险,正是因为它们使得项目的依赖变得“容易” - 因此你隐含信任的个人和组织的数量。(并且他们的可信度可能会突然变得更糟。)当语言的标准库存在重大差距时,第三方开发人员将热切地填补这些新的依赖关系,以便(不总是故意)继承。正在努力填补 JavaScript 标准库中的空白,我强烈支持这一点。
  社交媒体继续放大人们的坏情绪,社交媒体公司的一些高管仍然是问题的一部分。处理社交媒体的毒性和滥用是需要长期且多方面的努力,但我们可以立即做的一件事就是工程师、总经理、设计师和管理人员要将“参与”作为主要或唯一的“成功”的衡量标准。它具有游戏性,并且无法远程捕捉社交媒体上真人的真实体验。人们的经历往往非常糟糕,我们作为软件开发人员负责处理我们构建的结果。
  04
  展望未来
  我在 2018 年度过了一个愉快的时间,虽然从事低级别的防守(只是众多冒险中的一次),但是有很多工作要做。
  不幸的是,我发现最令人烦恼的问题(一般的滥用类别)并不属于我最专业的领域。我深入语言问题:有意义的界面、符合人体工程学和安全的库、内存安全性和类型安全性。但这把我虐得差点得心脏病。
  尽管如此,我看到人们确实提供了20年、10年或5年前似乎不可能实现的软件改进。我们真的在取得进步。以下是我想在2019年看到的:
  抛弃使用“参与”作为唯一或主要指标的想法。
  社会化工程社区的政策思考。是时候穿上我们成年人的衣服了。我们做的事情很重要(否则我们不会这样做,对吗?),这意味着我们需要考虑并处理后果。
  全面改善 Web 性能:这需要更大的 JavaScript 标准库;框架的性能改进;工具的改进;客户端改进。
  抛弃内存不安全是可以接受的想法,现在开发者可以使用安全的语言发布以前用了不安全语言编写的软件。这并不包括对现有应用程序的直接重写;大多数情况下,我看到的是对组件(如 Servo)分段的就地重写,以及已建立成熟类别的新应用程序(如 Xi 和CrosVM)。新的应用程序也让我们有机会重新思考旧的设计,正如 Xi 所做的那样(其跨平台、客户端/服务器、多前端设计)。
  用户体验、语言、库、框架将简化社会化,并在各个层面上消除复杂性。特别是,没有人应该用 C++ 开始一个新项目。

      上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号