在本页

权限

Deno 默认情况下是安全的。因此,除非您明确启用它,否则使用 Deno 运行的程序没有文件、网络或环境访问权限。访问安全敏感功能需要通过命令行标志或运行时权限提示向正在执行的脚本授予权限。这与 Node 的主要区别在于,Node 的依赖项会自动授予对所有内容的完全访问权限,从而在您的项目中引入隐藏的漏洞。

放心地运行不受信任的代码 跳转到标题

由于 Deno 默认情况下不提供 I/O 访问权限,因此它对于运行不受信任的代码和审核第三方代码非常有用。如果您正在构建或扩展一个运行用户生成代码的平台,您可以使用 Deno 安全地运行第三方代码,并通过 Deno Subhosting 或您选择的任何其他云平台托管此代码。

对于以下示例,mod.ts 已被授予对文件系统的只读访问权限。它不能写入文件系统,也不能执行任何其他安全敏感功能。

deno run --allow-read mod.ts

权限列表 跳转到标题

以下权限可用

  • --allow-env=<VARIABLE_NAME> 允许访问环境,例如获取和设置环境变量。从 Deno 1.9 开始,您可以指定一个可选的、用逗号分隔的环境变量列表,以提供允许的环境变量的白名单。
  • --allow-sys=<API_NAME> 允许访问提供有关用户操作系统的信息的 API,例如 Deno.osRelease()Deno.systemMemoryInfo()。您可以从以下列表中指定一个用逗号分隔的允许接口列表:hostnameosReleaseosUptimeloadavgnetworkInterfacessystemMemoryInfouidgid。这些字符串映射到 Deno 命名空间中提供操作系统信息的函数,例如 Deno.systemMemoryInfo
  • --allow-hrtime 允许高分辨率时间测量。高分辨率时间可用于计时攻击和指纹识别。
  • --allow-net=<IP/HOSTNAME> 允许网络访问。您可以指定一个可选的、用逗号分隔的 IP 地址或主机名列表(可选地带端口),以提供允许的网络地址的白名单。
  • --allow-ffi=<PATH> 允许加载动态库。您可以指定一个可选的、用逗号分隔的目录或文件列表,以提供允许加载的动态库的白名单。请注意,动态库不会在沙箱中运行,因此没有与 Deno 进程相同的安全限制。因此,请谨慎使用。请注意,--allow-ffi 是一个不稳定的功能。
  • --allow-read=<PATH> 允许文件系统读取访问。您可以指定一个可选的、用逗号分隔的目录或文件列表,以提供允许的文件系统访问的白名单。
  • --allow-run=<PROGRAM_NAME> 允许运行子进程。从 Deno 1.9 开始,您可以指定一个可选的、用逗号分隔的子进程列表,以提供允许的子进程的白名单。请注意,子进程不会在沙箱中运行,因此没有与 Deno 进程相同的安全限制。因此,请谨慎使用。
  • --allow-write=<PATH> 允许文件系统写入访问。您可以指定一个可选的、逗号分隔的目录或文件列表,以提供允许的文件系统访问白名单。
  • -A, --allow-all 允许所有权限。这将启用所有安全敏感功能。谨慎使用。

从 Deno 1.36 开始,以下标志可用

  • --deny-env=<VARIABLE_NAME> 拒绝环境访问,例如获取和设置环境变量。您可以指定一个可选的、逗号分隔的环境变量列表,以提供允许的环境变量白名单。此处指定的任何环境变量都将被拒绝访问,即使它们在 --allow-env 中指定。
  • --deny-sys=<API_NAME> 拒绝访问提供有关用户操作系统的 API。
  • --deny-hrtime 禁用高分辨率时间测量。高分辨率时间可用于计时攻击和指纹识别。
  • --deny-net=<IP/HOSTNAME> 禁用网络访问。您可以指定一个可选的、逗号分隔的 IP 地址或主机名(可选地带端口)列表,以提供网络地址黑名单。此处指定的任何地址都将被拒绝访问,即使它们在 --allow-net 中指定。
  • --deny-ffi=<PATH> 拒绝加载动态库。您可以指定一个可选的、逗号分隔的目录或文件列表,以提供允许加载的动态库黑名单。此处指定的任何库都将被拒绝访问,即使它们在 --allow-ffi 中指定。请注意,--deny-ffi 是一个不稳定的功能。
  • --deny-read=<PATH> 拒绝文件系统读取访问。您可以指定一个可选的、逗号分隔的目录或文件列表,以提供允许的文件系统访问黑名单。此处指定的任何路径都将被拒绝访问,即使它们在 --allow-read 中指定。
  • --deny-run=<PROGRAM_NAME> 拒绝运行子进程。您可以指定一个可选的、逗号分隔的子进程列表,以提供允许的子进程黑名单。请注意,子进程不会在沙箱中运行,因此没有与 Deno 进程相同的安全限制。因此,请谨慎使用。此处指定的任何程序都将被拒绝访问,即使它们在 --allow-run 中指定。
  • --deny-write=<PATH> 拒绝文件系统写入访问。您可以指定一个可选的、逗号分隔的目录或文件列表,以提供允许的文件系统访问黑名单。此处指定的任何路径都将被拒绝访问,即使它们在 --allow-write 中指定。

可配置权限 跳转到标题

某些权限允许您授予对特定实体(文件、服务器等)的访问权限,而不是授予对所有内容的访问权限。

文件系统访问 跳转到标题

此示例通过允许对 /usr 目录进行只读访问来限制文件系统访问。因此,执行失败,因为进程试图读取 /etc 目录中的文件

$ deno run --allow-read=/usr https://deno.land/[email protected]/examples/cat.ts /etc/passwd
error: Uncaught PermissionDenied: read access to "/etc/passwd", run again with the --allow-read flag
► $deno$/dispatch_json.ts:40:11
    at DenoError ($deno$/errors.ts:20:5)
    ...

通过允许访问 /etc 而不是 /usr,再次尝试使用正确的权限

deno run --allow-read=/etc https://deno.land/[email protected]/examples/cat.ts /etc/passwd

您可以进一步限制某些子路径不可访问,使用 --deny-read 标志

deno run --allow-read=/etc --deny-read=/etc/hosts https://deno.land/[email protected]/examples/cat.ts /etc/passwd
deno run --allow-read=/etc --deny-read=/etc/hosts https://deno.land/[email protected]/examples/cat.ts /etc/hosts
error: Uncaught PermissionDenied: read access to "/etc/hosts"...

--allow-write 的工作方式与 --allow-read 相同。

Windows 用户注意:/etc/usr 目录以及 /etc/passwd 文件在 Windows 上不存在。如果您想自己运行此示例,请将 /etc/passwd 替换为 C:\Windows\System32\Drivers\etc\hosts,并将 /usr 替换为 C:\Users

网络访问 跳转到标题

// fetch.js
const result = await fetch("https://deno.land/");

这是一个关于如何允许对特定主机名或 IP 地址进行网络访问的示例,可选地锁定到指定的端口

# Multiple hostnames, all ports allowed
deno run --allow-net=github.com,deno.land fetch.js

# A hostname at port 80:
deno run --allow-net=deno.land:80 fetch.js

# An IPv4 address on port 443
deno run --allow-net=1.1.1.1:443 fetch.js

# An IPv6 address, all ports allowed
deno run --allow-net=[2606:4700:4700::1111] fetch.js

您可以使用 --deny-net 标志限制某些域永远不可访问

# Allow to make network connections to all addresses except myserver.com.
deno run --allow-net --deny-net=myserver.com fetch.js

如果 fetch.js 尝试建立与任何未明确允许的主机名或 IP 的网络连接,相关调用将抛出异常。

允许对任何主机名/IP 进行网络调用

deno run --allow-net fetch.js

环境变量 跳转到标题

// env.js
Deno.env.get("HOME");

这是一个关于如何允许访问环境变量的示例

# Allow all environment variables
deno run --allow-env env.js

# Allow access to only the HOME env var
deno run --allow-env=HOME env.js

Windows 用户注意:环境变量在 Windows 上不区分大小写,因此 Deno 也以不区分大小写的方式匹配它们(仅限 Windows)。

您可以使用 --deny-env 标志限制某些环境变量永远不可访问

# Allow all environment variables except AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
deno run --allow-env --deny-env=AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY env.js

子进程权限 跳转到标题

子进程非常强大,但也可能有点可怕:它们可以访问系统资源,而不管您授予生成它们的 Deno 进程的权限。Unix 系统上的 cat 程序可用于从磁盘读取文件。如果您通过 Deno.run API 启动此程序,它将能够从磁盘读取文件,即使父 Deno 进程无法直接读取这些文件。这通常被称为权限提升。

因此,请务必仔细考虑是否要授予程序 --allow-run 访问权限:它实际上会使 Deno 安全沙箱失效。如果您确实需要生成特定可执行文件,可以通过将特定可执行文件名传递给 --allow-run 标志来降低风险,从而限制 Deno 进程可以启动的程序。

// run.js
const proc = Deno.run({ cmd: ["whoami"] });
# Allow only spawning a `whoami` subprocess:
deno run --allow-run=whoami run.js

# Allow running any subprocess:
deno run --allow-run run.js

您只能限制允许执行的可执行文件;如果授予执行权限,则可以传递任何参数。例如,如果您传递 --allow-run=cat,则用户可以使用 cat 读取任何文件。

您可以使用 --deny-run 标志限制某些可执行文件永远不可访问。

# Disallow spawning `git`.
deno run --allow-run --deny-run=git run.js