安全编程语言Rust迎来采用高峰

攻防
1年前

20221107214837.png

  无论是在大企业负责IT工作,还是玩自己的智能手机,你都肯定相当熟悉那无休无止的软件更新了,毕竟软件缺陷和安全漏洞那么多,不频繁更新太危险。是人就会犯错,所以代码无可避免会包含错误。但是,用名为Rust的编程语言编写软件的风潮正在兴起,因为Rust代码能够确保不出差错。用Rust编程,从设计上就不会意外引入那几类最常见的可利用安全漏洞,这是可以极大改善日常修复工作的一大优势,最终有望巩固全球网络安全基础。

  编程语言领域潮涨潮落,新贵来来去去,往往撑不住太久的时光。而Rust如今已历经12年岁月,从Mozilla研究人员的小副业,壮大成了一整套完善的生态系统。同时,其前身——至今仍广泛使用的C语言,今年也已50岁高龄。但由于Rust能产出更安全的代码,尤其是能在不降低性能的情况下产出安全代码,这一编程语言一直在稳步收获拥趸。时至今日,Rust终于站上了编程语言历史的转折点。微软、谷歌和AWS自2019年起就开始利用Rust。2020年,这三大科技巨头还与Mozilla和华为一起成立了非营利组织Rust基金会,以期维护和发展Rust语言。而经过两年紧锣密鼓的工作,Linux内核也在上月迈出了实现Rust支持的第一步。

  Android安全与隐私工程副总裁Dave Kleidermacher表示:“作为一种编程语言,Rust可谓蔚然成风,迎来病毒式普及。我们一直在Android和谷歌上投入Rust,很多工程师都在想,‘我该怎么开始尝试Rust?这玩意儿太棒了’。如今,Rust首次作为官方认可和接受的语言落地Linux。于是,不仅仅是Android,基于Linux的任何系统现在都可以开始引入Rust组件了。”

  Rust是所谓的“内存安全”语言,因为其旨在令程序无法从计算机内存中意外拉取非预期数据。如果使用C和C++等不具备这一属性的老派编程语言,程序员就不得不仔细检查自己程序请求的参数都是些什么数据,以及这些数据的获取方式——即使是技能纯熟、经验丰富的开发人员,在这方面也会偶尔犯错。而如果使用Rust编写新软件,即便是业余程序员也能确信自己没在代码里引入任何内存安全漏洞。

  程序的内存是共享资源,程序本身所有的功能和库都可以使用。以日历程序为例。如果用非内存安全的语言编写,当你打开日历并请求2022年11月2日的条目时,此程序会从分配来存储该日期数据的计算机内存块取得所有信息。这听起来没什么不对的。但如果程序未设置恰当的限制条件,且你一不小心请求了2022年11月42日的条目,那这日历程序就不会抛出错误或其他故障,而是尽职尽责地去存储其他数据的内存区域读取信息返回给你了——可能是你用来保护日历的密码,也可能是你为了使用付费日历功能而保存在文件里的信用卡号。此外,如果你往11月42日的日程上添加一条“生日聚会”的条目,这个日历程序可能会覆盖掉内存中的无关数据,而不是告诉你无法完成此项任务。这就是所谓的“越界”读写漏洞,攻击者可以利用这种漏洞不当访问数据,甚或扩展系统控制。

  另一种常见的内存安全漏洞是“释放后使用”(use-after-free),比如程序已经释放了一块内存(可能你删除了2022年10月的所有日历条目),但却错误地保留了访问途径(如未将指向此块内存的指针置为NULL)。后续如果你请求10月17日的数据,程序就可能会抓取最终存在那里的任何数据。而代码中内存安全漏洞的存在也给黑客带来了机会,他们可以精心编造恶意日历邀请,用刻意选择的日期或事件详细信息来篡改内存,最终获得远程访问权限。

  以上几类漏洞不是什么深奥神秘的软件漏洞。研究和审计已反复指出,这些漏洞广泛存在于软件中,占了所有软件漏洞的绝大部分。所以,尽管你用Rust编程也还会犯错和造成安全缺陷,但杜绝内存安全漏洞的机会却是巨大的。

  “内存安全问题是绝大部分漏洞的罪魁祸首,而且藏身在操作系统、手机和基础设施等关键应用中。”软件供应链安全公司Chainguard首席执行官Dan Lorenc说道,“大家都在用内存不安全语言编写代码的那几十年里,我们尝试过改进和构建更好的工具,也教导程序员不要犯此类错误,但让人努力避免犯错的话语到底能起多大作用却是有限的。所以,我们需要的是一种新技术,能够直接杜绝引入这一类漏洞的新技术,而这正是Rust最终所带来的。”

  并非没有人怀疑和批判Rust。过去两年在Linux中实现Rust的工作充满争议,其中部分原因在于添加对任何其他语言的支持肯定会增加复杂性,也有部分原因关乎如何具体实现这一切的争论。支持者强调,Rust具备必要的元素(不会导致性能损耗,且与其他语言编写的软件互操作良好),而且就凭能够满足当下的迫切需求,Rust也很重要。

  “与其说Rust是正确的选择,不如说时机已经成熟。”长期开源贡献者兼研究者Lorenc表示,“现在除了什么都不做,没有其他真正的备选项,这已经不再是一个选择了。再用十年内存不安全的代码可能给科技行业,给国家安全,给所有一切都带来大麻烦。”

  然而,转向Rust的最大挑战之一,恰恰是开发人员已经花了几十年时间用内存不安全语言编写重要代码。用Rust语言编写新软件并不能解决这一巨大存量。比如说,Linux内核实现就始于外设,支持基于Rust的驱动程序,即在操作系统和打印机等硬件兼协调的程序。

  “做操作系统的时候,速度和性能始终是首要考虑,用C++或C语言执行的部分通常也是你无法用Java或其他内存安全语言执行的部分,因为性能跟不上。”谷歌的Kleidermacher说道,“因此,想要能够运行Rust还具有同样的性能,而且还保证内存安全,真的很酷。但这是段旅程。你无法一夜之间就重写5000万行代码,所以我们仔细挑选安全关键组件,随着时间的推移逐步改进其他东西。”

  Kleidermacher表示,Android的很多加密密钥管理功能如今都用Rust编写了,还有私密互联网通信功能DNS over HTTPS、新版超宽带芯片栈,以及谷歌定制Tensor G2芯片中使用的新Android虚拟化框架。Android团队正逐渐将蓝牙和Wi-Fi等连接栈转换为Rust,因为这些东西都基于复杂的行业标准,很容易含有许多漏洞。简言之,目前的策略就是先将最暴露或最重要的软件组件转换成Rust,然后向内发力,开始获取增量安全收益。 

  美国加州公益公司Internet Security Research Group运营着内存安全计划Prossimo和免费证书颁发机构Let's Encrypt,其执行董事Josh Aas如此说道:“没错,工作量很大,未来也不轻松,但科技行业财大气粗,而且天才程序员层出不穷,怕什么呢?我们又不是没有资源。问题仅仅在于工作量大已经很不错了。”

  而在Rust转向主流的同时,内存安全问题需要某种解决方案的呼声似乎也越来越大。就在本周,若非没有采用内存安全语言编写,常用安全通信库OpenSSL中的一个高危漏洞是本可以被阻止的。不同于2014年臭名昭著的OpenSSL漏洞“心脏出血”(Heartbleed,潜伏两年未曝出,导致全网站点面临数据拦截攻击风险),尽管这几年来业内一直在努力减少内存安全漏洞,这个新漏洞却仍在近几个月里被引入到了OpenSSL中。

  “有多少人正苦于内存安全漏洞导致的身份盗窃噩梦?而在国家安全层面上,网络攻击威胁又有多少是内存安全漏洞造成的?”Aas表示,“在我看来,如今整个症结所在,不过是说服大家投入其中而已。关键在于我们是否足够了解这一威胁,以及我们是否有意愿解决这一威胁。


参考阅读
不常见编程语言成攻击利器
【调查】编程语言安全漏洞一览
AI权限管控、内存指令安全与后门发现:第三代安全引擎的三个创新应用