Deno 作为 JavaScript 运行时,通过要求代码访问外部世界时必须获得明确权限,将其市场定位为“默认安全”。然而,一项技术批评指出,这种模型从根本上是不安全的,因为它通过过滤标准库调用来模拟系统级安全,而不是在操作系统层面隔离进程。

展示 Deno 安全模型技术批评的代码列表截图。
源分析中的代码列表,详细说明了 Deno 权限系统的技术缺陷。goldstein.lol

此图提供了对用于批评 Deno 安全模型的特定代码级分析的视觉参考。

源页面中关于 Deno 安全模型的第二个代码列表截图。
源分析中突出的特定漏洞向量的额外代码示例。goldstein.lol

此图通过展示安全批评的更多技术细节来补充第一张图。

终端提示的漏洞

Deno 的权限系统在终端中显示交互式提示,在运行时请求用户授权。由于这些提示作为纯文本发送到 stdout 并从 stdin 接收输入,它们与正在执行的潜在恶意代码共享相同的通信通道。

攻击者可以操纵终端颜色或使用非标准的转义代码来隐藏或伪造这些提示。这会导致用户在提示出现前,由于代码修改了终端状态,而在不知情的情况下批准了请求。

“Deno 进程实际上并没有被沙箱化,它只是在假装被沙箱化。”

— I’m not a fan of Deno’s security model | max’s place

通过环境变量逃逸沙箱

“--allow-run”标志旨在允许程序执行特定命令,例如“uname”。然而,由于程序是按名称而非唯一路径识别的,攻击者可以通过修改 PATH 环境变量,使其指向具有相同名称的恶意二进制文件。

此外,即使 PATH 已被保护,大多数可执行文件仍使用动态加载器,而动态加载器可能会受到如 LD_PRELOAD 等环境变量的影响。通过将恶意库注入加载过程,攻击者可以在加载时执行任意代码,从而有效地绕过 Deno 的权限检查。

伪沙箱与真实隔离

识别出的核心问题是 Deno 不是真正的沙箱;它是一个过滤自身标准库 API 的运行时。一旦程序通过 Deno 特定库之外的手段与操作系统交互,这种方法就会失效。

虽然 Deno 的模型可能保护免受“低智”恶意代码的攻击,但对于高风险的不可信执行,它提供了一种虚假的安全感。作者得出结论:唯一的稳健解决方案是使用真正的操作系统级沙箱来完全隔离进程,而不是试图管理允许的标准库调用列表。