开发者生态
morning
我不喜欢 Deno 的安全模型 (2024)
摘要
I’m not a fan of Deno’s security model (published on August 31, 2024) this has been bothering me for a while now, so I want to write down my thoughts so I can get it out of my head and move on. we’re ...
the
Deno
and
this
allow
read
can
permissions
not
for
2026-11-09
1 阅读
约6分钟阅读
maxloh
字号:
我不喜欢 Deno 的安全模型(发布于 2024 年 8 月 31 日),这已经困扰我一段时间了,所以我想写下我的想法,这样我就可以把它从我的脑海中赶走并继续前进。我们将讨论 Deno 如何实现安全性,特别是其权限系统,以及为什么我认为这种方法从根本上来说是不安全且具有误导性的。等等,Deno 是什么? Deno 是 JavaScript 的语言运行时。它由一个标准库、一个包管理器、一个 TypeScript 转译器和一堆对我们的故事不重要的其他东西组成。它不是 JavaScript 实现,因此它不会解释或编译 JavaScript,而是为此重用 V8。 Deno 的旗舰功能之一是它的权限系统(它位于登陆页面的“默认安全”标题下)。这个想法很简单:由于 Deno 中运行的 JS 代码需要标准库来访问外部世界,Deno 可以选择允许或禁止哪些访问,因此当您运行 shell deno run --allow-read = /tmp/dir --allow-run = uname code.ts 时,标准库将只允许 code.ts 读取 /tmp/dir 并运行 uname 。此外,程序可以在运行时请求权限,因此像 typescript const r = { name : "read" , path : "/tmp/dir" } as const 那样的代码;等待德诺。权限。请求(r);将在终端中显示一个漂亮的小提示:┌⚠️ Deno 请求对“/tmp/dir”的读取访问权限。 ├ 由 `Deno.permissions.request()` API 请求。 ├ 使用 --allow-read 再次运行以绕过此提示。 └ 允许? [y/n/A](y = 是,允许;n = 否,拒绝;A = 允许所有读取权限)> 您可以授予或拒绝它。 (旁白:我真的很怀念浏览器扩展中的这个功能。目前,如果您的扩展需要潜在访问任何网站,它需要请求对所有网站的实际访问,这不太理想)如果您喜欢谜题,那么您可以停下来思考这个系统可能会出现什么问题。两个具体问题中的提示问题我想指出的是这是不太严重的一个。我们将首先讨论它,因为这是我注意到的第一件事,当我第一次读到这一点时,它立即让我感到厌烦。 (如果您只对更有趣的部分感兴趣,您可以跳到下一部分)。因此,这个漂亮的小提示会显示在终端中。它不像 PolKit GUI 窗口或任何东西,它只是标准输出上等待来自标准输入的输入的文本。这是一件疯狂的事情。你看,终端有一个有点奇怪的 API。应用程序可以发送到终端的大多数命令/请求都是通过将它们打印到标准输出来带内发送的。然后终端可以通过向标准输入发送数据来进行回复。由于 Deno 允许程序将任意数据打印到 stdout 并从 stdin 读取,而无需任何权限或进行任何过滤,因此恶意代码可以向终端发送任意命令。通常没问题,因为终端不会仅仅因为 stdout 告诉它们就执行 shell 命令,您应该能够自由地 cat 文件,而不会冒任意代码执行的风险。如果您允许恶意代码对终端执行任何操作,然后在同一终端上打印提示,则显然不太好。您可以通过修改终端颜色来隐藏提示。 (这个在 2026 年被关闭,因为权限提示是“部分可见”(你可以看到表情符号)并且“人工智能代理倾向于”改变终端颜色,所以这是一个“有效的用例”)或者欺骗用户将批准预先输入到 stdin 中。或者欺骗终端将批准输入到标准输入中作为对某些请求的响应。 (终端永远不会向标准输入发送 Enter 以避免执行命令,但“按 Enter 继续”很常见,因此不会引起怀疑;用户永远不会看到实际的提示)。这是一个 asciicast,我认为它看起来很酷。截屏视频中的具体问题已得到长期修复;终端颜色的问题不是。这并不重要,因为真正的问题是使用攻击者控制的通道来获取安全敏感信息。这就像在网页上执行攻击者控制的 JS 代码,然后在同一页面上要求输入密码。你无法知道页面是否处于安全状态,因此你不能信任任何输入。即使 Deno 设法用“标准”转义码修补每个问题,你也永远不知道那里存在哪些非标准代码。许多终端都有一些,无法预测它们将如何与您的提示进行交互。 (旁白:为什么 sudo 可以做到这一点?区别在于 sudo 在运行任何其他代码之前首先要求输入密码。要以这种方式欺骗 sudo,您需要在键入 sudo 之前搞乱终端状态,并且足够安静,以便在键入时不会注意到它。如果某些终端允许它,我会认为它是终端中的错误) --allow-run 问题,所以,我上面写的这个命令有一个奇怪的事情(我将将其复制到此处以供参考): shell deno run --allow-read = /tmp/dir --allow-run = uname code.ts 做什么
这篇文章对您有帮助吗?
订阅66必读
每日精选科技资讯,直达你的邮箱