当前位置: 首页 > 科技观察

WebAssembly安全性的现在和未来

时间:2023-03-13 09:04:38 科技观察

正如我们最近解释的那样,WebAssembly是一种二进制格式,适用于用任何语言编写的软件,旨在最终在任何平台上运行而无需更改。WebAssembly的第一个应用是在网络浏览器中,使网站更快、更具交互性。WebAssembly计划超越网络,从各种服务器到物联网(IoT),创造了许多机会,但也带来了许多安全问题。这篇文章是对这些问题和WebAssembly安全模型的介绍性概述。WebAssembly很像JavaScript。在Web浏览器中,WebAssembly模块由执行JavaScript代码的同一虚拟机(VM)管理。因此,WebAssembly与JavaScript一样,造成同样的危害,但效率更高,不易被发现。由于JavaScript是纯文本,需要浏览器编译后才能运行,而WebAssembly是一种可以立即运行的二进制格式,运行速度更快,也更难扫描出(即使使用杀毒软件)恶意指令。WebAssembly的这种“代码混淆”效果已被用来弹出未经请求的广告,或打开虚假的“技术支持”窗口询问敏感数据。另一个技巧是自动将浏览器重定向到包含真正危险的恶意软件的“登陆”页面。最后,就像JavaScript一样,WebAssembly可用于“窃取”处理能力而不是数据。2019年,对150个不同WASM模块的分析发现,其中约32%用于加密货币挖掘。WebAssembly沙箱和接口WebAssembly代码运行在一个由虚拟机(而不是操作系统)管理的“沙箱”中。这可以防止它看到主机,并直接与它交互。只能通过虚拟机提供的WebAssembly系统接口(WASI)访问系统资源(文件、硬件或互联网连接)。WASI与大多数其他应用程序编程接口(API)不同,它具有独特的安全功能,真正推动了WASM在传统服务器和边缘计算场景中的采用,这将是下一篇文章的主题。在这里,可以说从网络转移到其他环境时,其安全影响可能会大不相同。现代网络浏览器是非常复杂的软件,但它们是建立在几十年的经验和数十亿人的日常测试的基础上的。与浏览器相比,服务器或物联网(IoT)设备几乎是未知领域。这些平台的虚拟机需要扩展WASI,因此肯定会带来新的安全挑战。WebAssembly中的内存和代码管理与普通的编译程序相比,WebAssembly应用程序对内存和自身的访问非常有限。WebAssembly代码不能直接访问未被调用的函数或变量,不能跳转到任意地址,不能像字节码指令一样执行内存中的数据。在浏览器内部,WASM模块只能获取一个全局的连续字节数组(线性内存)进行操作。WebAssembly可以直接读写这个区域的任何地方,或者请求增加它的大小,但仅此而已。这个线性内存也与包含其实际代码、执行堆栈,当然还有运行WebAssembly的虚拟机的区域分开。对于浏览器来说,所有这些数据结构都是普通的JavaScript对象,使用标准过程与所有其他对象隔离开来。结果还可以,但并不完美。所有这些限制使得行为不端的WebAssembly模块变得困难,但并非不可能。沙盒内存使得WebAssembly几乎不可能从外部接触东西,它也让操作系统更难防止内部发生坏事。传统的内存监控机制,如StackCanaries,它会注意到代码是否试图弄乱它不应该的对象,在这里是无用的。事实上,WebAssembly只能访问自己的线性内存,但可以直接访问,这也可能为攻击者的行为提供便利。有了这些限制和对模块源代码的访问,就可以更容易地猜测要覆盖哪些内存位置可能会造成最大的损害。销毁局部变量似乎也是可能的,因为它们保留在线性内存中的无监督堆栈中。2020年一篇关于WebAssembly二进制安全性的论文指出,WebAssembly代码仍然可以覆盖设置常量内存中的字符串文字。同一篇论文描述了WebAssembly如何比在三个不同平台(浏览器、Node.JS上的服务器端应用程序和独立WebAssembly虚拟机中的应用程序)上编译为本机二进制文件时更不安全。方式。建议进一步阅读该主题。一般来说,WebAssembly只能破坏其自身沙箱中的内容的想法可能会产生误导。WebAssembly模块为调用它们的JavaScript代码完成了繁重的工作,每次都交换变量。如果一个模块编写了不安全的JavaScript代码,在这些变量中的任何一个中调用WebAssembly,它可能会导致崩溃或数据泄露。未来方向WebAssembly的两个新兴特性:并发性和内部垃圾收集,肯定会影响其安全性(如何以及影响多少,现在说还为时过早)。并发允许多个WebAssembly模块在同一个虚拟机中并行运行。目前,这只能通过JavaScriptwebworkers实现,但更好的机制正在开发中。在安全方面,他们可能会引入很多以前不需要的代码,也就是出错的方式更多。为了性能和安全,我们需要一个本地垃圾收集器,但最重要的是,在经过良好测试的浏览器的Java虚拟机之外使用WebAssembly,因为这些虚拟机无论如何都会在内部收集所有垃圾。当然,即使是这个新代码也可能成为漏洞和攻击的另一个切入点。从好的方面来说,有一些通用策略可以使WebAssembly比现在更安全。这些策略包括:编译器改进、栈/堆和常量数据的独立线性存储机制、避免使用C等不安全语言编译WebAssembly模块代码。