5月27日 20:11

Deno 的权限系统是如何工作的?

Deno 采用"默认拒绝"的安全模型——脚本启动时没有任何权限,必须通过命令行标志显式授权才能访问文件、网络、环境变量等资源。这套权限系统是 Deno 区别于 Node.js 的核心安全特性。

核心机制

权限以 --allow-* 标志授予,支持通配和精确指定两种模式:

bash
# 通配:允许所有网络访问 deno run --allow-net app.ts # 精确:只允许访问指定域名 deno run --allow-net=api.example.com app.ts

主要权限标志包括 --allow-read--allow-write--allow-net--allow-env--allow-run--allow-sys--allow-hrtime--allow-ffi,均可通过 = 指定白名单。Deno 1.36 起还支持 --deny-* 黑名单,优先级高于 --allow-*,可在宽泛授权下排除特定资源。

运行时权限查询

代码中可通过 Deno.permissions API 检查和请求权限:

typescript
const status = await Deno.permissions.query({ name: "net" }); // status.state → "granted" | "prompt" | "denied" const req = await Deno.permissions.request({ name: "read", path: "/tmp" }); // 运行时弹出交互提示

也可调用 Deno.permissions.revoke() 主动放弃已获权限,实现最小权限的动态收缩。

子进程权限的陷阱

--allow-run 授予的子进程不在 Deno 沙箱内运行,它继承宿主系统的完整权限,不受 Deno 权限标志约束。因此只应允许运行明确可信的命令,如 --allow-run=git,curl

与 Node.js 的关键区别

Node.js 默认拥有全部系统权限,依赖 fs 模块即可读写任意文件,安全边界完全依赖操作系统层面。Deno 则从运行时层面强制权限隔离,每个资源访问请求都需经过权限检查,恶意依赖无法静默越权。

追问

  • 权限白名单和黑名单同时存在时,哪个优先? --deny-* 优先。即使 --allow-read=/app 已授权,--deny-read=/app/secret 仍会阻止对该目录的访问。
  • 如何在 CI 中自动处理权限提示? 使用 --no-prompt 标志,未授权的访问直接抛出 PermissionDenied 错误而非交互提示,适合自动化流水线。
标签:Deno