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 检查和请求权限:
typescriptconst 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 错误而非交互提示,适合自动化流水线。