WebAssembly,有时称为WASM,是在Web浏览器虚拟机(VM)中执行的便携式,低级二进制代码指令格式。它使开发人员能够以各种语言编写高性能代码,并与JavaScript一起运行。
开发人员正在拥抱WebAssembly,因为其能够加速复杂算法,启用游戏和多媒体应用程序,并为运行不信任的代码提供安全的沙盒环境。但是,在采用WebAssembly之前,要考虑其安全含义以及如何减轻风险的关键。
顶级WebAssmbly安全问题
开发人员可以将许多现代编程语言编译为WebAssembly。但是,尽管具有优势,但WebAssembly可以绕过传统的安全措施,可能在浏览器中执行恶意代码。
让我们通过使用开源Web框架Blazor构建示例应用程序来仔细研究WebAssembly的独特安全问题。大餐让我们为我们的网页编写C#代码而不是JavaScript。 C#代码内置在Dynamic Link库(DLL)和WebAssembly(.WASM)文件上,在客户端浏览器上运行。
先决条件
在进入本教程之前,请确保您有以下内容:
- 下载并安装Visual Studio或VS Code。这是您将用来编写和运行WebAssembly代码的集成开发环境(IDE)。如果选择VS代码,请下载并安装.NET SDK和C# extension下一个。
- 为代码安装Visual Studio extension或Snyk extension。该插件将扫描并在我们的WebAssembly代码上提供安全分析。
- 下载sample project。
运行样本项目
如果您为IDE选择了Visual Studio,请打开Visual Studio Installer并检查 .NET WebAssembly构建工具选项:
打开工具>选项> snyk 菜单,然后一般设置。接下来,单击将Visual Studio连接到Snyk.io 按钮。
如果选择VS代码作为IDE,请单击左工具栏中的SNYK图标。接下来,单击信任工作区并连接。
在Visual Studio或VS代码中运行该程序以启动示例应用程序,该应用看起来像以下屏幕截图,并带有“人力资源”标题,图像和文本。
安全关注#1:WebAssembly模块隔离
要使用此技术维护Web应用程序的安全性,您必须将WebAssembly模块保持隔离。彼此隔离模块,主机环境意味着它们每个人都独立运行,而不会干扰其他模块或主机应用程序的行为。执行不信任代码时,模块隔离至关重要 - 它阻止恶意代码访问敏感数据或资源。
实现模块隔离的两个最佳实践是沙箱和分隔。
沙盒涉及将每个模块放置在一个限制对主机系统和其他模块的单独隔离环境中。下图显示了一个带有两个WebAssembly模块的项目( Finance 和人力资源)。将项目编译和部署到Web浏览器时,WebAssembly模块在与主机运行时分开的沙盒环境中执行。
隔间化涉及将主机应用程序及其模块划分为单独的隔室,每个隔间都有其自己的资源和访问权限。
沙箱和隔室化创建了一个安全的环境,可以执行不受信任的代码而不会损害主机系统或其他模块的安全性。
接下来,使用Snyk Visual Studio代码扩展名来验证WebAssembly代码是否易受伤害。打开扩展名> snyk 菜单,然后单击扫描。
Snyk分析文件并标识已知的WebAssembly 代码质量问题以及与开源和代码安全有关的问题和漏洞。如果发现问题或漏洞,Snyk提供了有关如何解决问题的问题的详细信息和建议。
安全问题2:WebAssembly线性内存模型
线性内存模型是一种使用单个连续地址空间来组织内存的内存寻址技术。这种方法允许处理单元直接和顺序地访问存储位置。下图显示了使用线性内存中的空间之间的JavaScript和WebAssembly代码之间共享的对象。
WebAssembly线性内存模型功能允许模块分配和访问连续的内存块,就像传统数组一样。尽管此模型提供了一种管理WebAssembly应用程序中内存的快速有效方法,但它也引入了安全风险。
例如,如果模块在其分配范围之外访问内存,则可能会破坏其他模块或主机系统的内存。这种情况可能导致崩溃或安全漏洞。
为了减轻WebAssembly应用程序中与线性内存模型相关的安全风险,请遵循以下最佳实践:
- 使用界限检查以确保模块仅在其分配范围内访问内存。
- 避免不安全的功能以防止记忆损坏漏洞。
- 实施内存保护机制,例如地址空间布局随机化(ASLR)和数据执行预防(DEP)。
安全问题3:WebAssembly JIT编译
WebAssembly Just-time(JIT)编译将WASM代码汇编为计算机代码,而不是提前。虽然此过程提供了重大的性能优势,但它也引入了潜在的安全风险。
JIT汇编的动态性质使检测和预防攻击变得复杂。坏参与者可以将恶意代码注入汇编过程并在主机环境中执行。例如,黑客可以制作一个用高级编程语言编写的非正式常数:
var a = (0x11223344^0x44332211^0x44332211^ ...);
然后,JIT编译器将指令转换为一系列本机X86代码指令:
0000: b8 44 33 22 11 mov $0x11223344,%eax mov eax,0x11223344
0005: 35 11 22 33 44 xor $0x44332211,%eax xor eax,0x44332211
000a: 35 11 22 33 44 xor $0x44332211,%eax xor eax,0x44332211
攻击者使用已知的错误将执行指针移动以地址0001。这执行了一套恶意指令,这些指令精心制作并注入上面的常数。
为了减轻WebAssembly应用程序中JIT汇编的安全风险,实施以下最佳实践来管理编译过程:
- 在运行时使用提前(AOT)编译将WASM代码编译到机器代码中。这种方法消除了与动态汇编相关的风险。
- 在JIT编译器中应用安全补丁。
安全关注#4:Web API和跨站点脚本(XSS)
WebAssembly可以与Web API进行交互,以从Web浏览器,服务器和其他平台访问资源和数据。但是,这些相互作用可以引入cross-site scripting (XSS) attacks等安全风险。在XSS攻击中,黑客将恶意代码注入网页或应用程序。后来,用户可能会在不知不觉中执行此恶意代码,从而导致未经授权的访问或数据盗窃。
到WebAssembly应用程序中的mitigate the risks of XSS attacks,实施最佳实践以进行输入验证和输出编码:
- 输入验证检查用户输入是否可能是恶意代码或字符,并拒绝不符合特定条件的任何输入。
- 输出编码涉及编码用户输入或输出以防止执行恶意代码。
此外,请使用HTTP在服务器和客户端之间加密数据,以防止攻击者拦截和修改运输中的数据。
安全问题#5:不安全的WebAssembly内容交付
安全的内容交付对于WebAssembly应用程序至关重要,确保用户通过可信赖的频道接收真实的,不变的代码。不安全的内容交付可以引入安全风险,包括中间人(MITM)攻击和代码篡改。
MITM攻击涉及攻击者在服务器和客户端之间传递时拦截和修改代码。该技术允许攻击者将恶意代码注入应用程序,浏览器或WASM运行时可以执行该应用程序。
要确保WebAssembly应用程序中的内容交付,请遵循以下最佳实践:
- 使用https在服务器和客户端之间加密数据,以确保安全和不变的代码传输。
- 使用校验和数字签名之类的内容完整性检查来验证代码真实性。
- 实施访问控制机制以限制代码访问授权用户的访问。
安全地组装
开发人员热情地采用了WebAssembly,该技术使他们可以在Web浏览器中编写高性能应用程序。但是,WebAssembly的好处带来了严重的安全问题。
本文介绍了一些WebAssembly安全性问题:不当模块隔离,线性内存模型缺乏保护,JIT编译器漏洞,跨站点脚本攻击以及不安全的WebAssembly内容交付。
幸运的是,几种最佳实践可以减轻WebAssembly引入的漏洞。遵循这些安全措施有助于保护用户并屏蔽其WebAssembly应用程序。
为了保护您的系统和用户,跟上影响WebAssembly的最新安全威胁也至关重要。开发工具有帮助。例如,SNYK平台维护着大量已知漏洞的目录,并提供了可行的见解以减轻这些风险。 Snyk Code和Snyk Open Source等工具使您能够快速检测和解决代码安全问题。立即开始您的免费帐户。