- assert 断言
- async_hooks 异步钩子
- async_hooks/context 异步上下文
- buffer 缓冲区
- C++插件
- C/C++插件(使用 Node-API)
- C++嵌入器
- child_process 子进程
- cluster 集群
- CLI 命令行
- console 控制台
- Corepack 核心包
- crypto 加密
- crypto/webcrypto 网络加密
- debugger 调试器
- deprecation 弃用
- dgram 数据报
- diagnostics_channel 诊断通道
- dns 域名服务器
- domain 域
- Error 错误
- events 事件触发器
- fs 文件系统
- global 全局变量
- http 超文本传输协议
- http2 超文本传输协议 2.0
- https 安全超文本传输协议
- inspector 检查器
- Intl 国际化
- module 模块
- module/cjs CommonJS 模块
- module/esm ECMAScript 模块
- module/package 包模块
- net 网络
- os 操作系统
- path 路径
- perf_hooks 性能钩子
- permission 权限
- process 进程
- punycode 域名代码
- querystring 查询字符串
- readline 逐行读取
- repl 交互式解释器
- report 诊断报告
- sea 单个可执行应用程序
- stream 流
- stream/web 网络流
- string_decoder 字符串解码器
- test 测试
- timers 定时器
- tls 安全传输层
- trace_events 跟踪事件
- tty 终端
- url 网址
- util 实用工具
- v8 引擎
- vm 虚拟机
- wasi 网络汇编系统接口
- worker_threads 工作线程
- zlib 压缩
Node.js v20.18.0 文档
- Node.js v20.18.0
- 目录
-
导航
- assert 断言
- async_hooks 异步钩子
- async_hooks/context 异步上下文
- buffer 缓冲区
- C++插件
- C/C++插件(使用 Node-API)
- C++嵌入器
- child_process 子进程
- cluster 集群
- CLI 命令行
- console 控制台
- Corepack 核心包
- crypto 加密
- crypto/webcrypto 网络加密
- debugger 调试器
- deprecation 弃用
- dgram 数据报
- diagnostics_channel 诊断通道
- dns 域名服务器
- domain 域
- Error 错误
- events 事件触发器
- fs 文件系统
- global 全局变量
- http 超文本传输协议
- http2 超文本传输协议 2.0
- https 安全超文本传输协议
- inspector 检查器
- Intl 国际化
- module 模块
- module/cjs CommonJS 模块
- module/esm ECMAScript 模块
- module/package 包模块
- net 网络
- os 操作系统
- path 路径
- perf_hooks 性能钩子
- permission 权限
- process 进程
- punycode 域名代码
- querystring 查询字符串
- readline 逐行读取
- repl 交互式解释器
- report 诊断报告
- sea 单个可执行应用程序
- stream 流
- stream/web 网络流
- string_decoder 字符串解码器
- test 测试
- timers 定时器
- tls 安全传输层
- trace_events 跟踪事件
- tty 终端
- url 网址
- util 实用工具
- v8 引擎
- vm 虚拟机
- wasi 网络汇编系统接口
- worker_threads 工作线程
- zlib 压缩
- 其他版本
权限#
¥Permissions
权限可用于控制 Node.js 进程可以访问哪些系统资源,或者进程可以对这些资源执行哪些操作。权限还可以控制其他模块可以访问哪些模块。
¥Permissions can be used to control what system resources the Node.js process has access to or what actions the process can take with those resources. Permissions can also control what modules can be accessed by other modules.
-
基于模块的权限 控制在应用执行期间哪些文件或 URL 可供其他模块使用。例如,这可用于控制第三方依赖可以访问哪些模块。
¥Module-based permissions control which files or URLs are available to other modules during application execution. This can be used to control what modules can be accessed by third-party dependencies, for example.
-
基于进程的权限 控制 Node.js 进程对资源的访问。可以完全允许或拒绝资源,或者可以控制与其相关的操作。例如,可以允许文件系统读取而拒绝写入。此功能无法防止恶意代码。根据 Node.js 安全政策,Node.js 信任要求它运行的任何代码。
¥Process-based permissions control the Node.js process's access to resources. The resource can be entirely allowed or denied, or actions related to it can be controlled. For example, file system reads can be allowed while denying writes. This feature does not protect against malicious code. According to the Node.js Security Policy, Node.js trusts any code it is asked to run.
权限模型实现了 "安全带" 方法,可防止受信任的代码无意中更改文件或使用未明确授予访问权限的资源。它在存在恶意代码的情况下不提供安全保障。恶意代码可以绕过权限模型并执行任意代码,而不受权限模型施加的限制。
¥The permission model implements a "seat belt" approach, which prevents trusted code from unintentionally changing files or using resources that access has not explicitly been granted to. It does not provide security guarantees in the presence of malicious code. Malicious code can bypass the permission model and execute arbitrary code without the restrictions imposed by the permission model.
如果你发现潜在的安全漏洞,请参阅我们的 安全政策。
¥If you find a potential security vulnerability, please refer to our Security Policy.
基于模块的权限#
¥Module-based permissions
政策#
¥Policies
¥Stability: 0 - Deprecated: Will be removed shortly
Node.js 包含了对创建加载代码的策略的实验性支持。
¥Node.js contains experimental support for creating policies on loading code.
策略是一种安全功能,旨在确保加载代码的完整性。
¥Policies are a security feature intended to ensure the integrity of the loaded code.
虽然它不能作为追踪代码来源的来源机制,但它可以作为针对恶意代码执行的强大防御。与基于运行时的模型在加载代码后可能会限制功能不同,Node.js 策略的重点是首先防止恶意代码完全加载到应用中。
¥While it does not function as a provenance mechanism to trace the origin of code, it serves as a robust defense against the execution of malicious code. Unlike runtime-based models that may restrict capabilities once the code is loaded, Node.js policies focus on preventing malicious code from ever being fully loaded into the application in the first place.
策略的使用假定策略文件的安全实践,例如确保 Node.js 应用不能使用文件权限覆盖策略文件。
¥The use of policies assumes safe practices for the policy files such as ensuring that policy files cannot be overwritten by the Node.js application by using file permissions.
最佳实践是确保正在运行的 Node.js 应用的策略清单是只读的,并且正在运行的 Node.js 应用不能以任何方式更改该文件。一个典型的设置是将策略文件创建为与运行 Node.js 的用户 ID 不同的用户 ID,并向运行 Node.js 的用户 ID 授予读取权限。
¥A best practice would be to ensure that the policy manifest is read-only for the running Node.js application and that the file cannot be changed by the running Node.js application in any way. A typical setup would be to create the policy file as a different user id than the one running Node.js and granting read permissions to the user id running Node.js.
启用#
¥Enabling
--experimental-policy
标志可用于在加载模块时启用策略特性。
¥The --experimental-policy
flag can be used to enable features for policies
when loading modules.
一旦设置好,则所有模块都必须符合传给标志的策略清单文件:
¥Once this has been set, all modules must conform to a policy manifest file passed to the flag:
node --experimental-policy=policy.json app.js
策略清单将用于对 Node.js 加载的代码强制约束。
¥The policy manifest will be used to enforce constraints on code loaded by Node.js.
为了减少对磁盘上策略文件的篡改,可以通过 --policy-integrity
提供策略文件本身的完整性。这允许运行 node
并断言策略文件内容,即使文件在磁盘上被更改。
¥To mitigate tampering with policy files on disk, an integrity for
the policy file itself may be provided via --policy-integrity
.
This allows running node
and asserting the policy file contents
even if the file is changed on disk.
node --experimental-policy=policy.json --policy-integrity="sha384-SggXRQHwCG8g+DktYYzxkXRIkTiEYWBHqev0xnpCxYlqMBufKZHAHQM3/boDaI/0" app.js
特性#
¥Features
错误行为#
¥Error behavior
当策略检查失败时,Node.js 默认会抛出错误。通过在策略清单中定义 "onerror" 字段,可以将错误行为更改为几种可能性之一。以下值可用于更改行为:
¥When a policy check fails, Node.js by default will throw an error. It is possible to change the error behavior to one of a few possibilities by defining an "onerror" field in a policy manifest. The following values are available to change the behavior:
-
"exit"
:将立即退出进程。不允许运行任何清理代码。¥
"exit"
: will exit the process immediately. No cleanup code will be allowed to run. -
"log"
:将在发生故障的地方记录错误。¥
"log"
: will log the error at the site of the failure. -
"throw"
:将在失败的地方抛出 JS 错误。这是默认值。¥
"throw"
: will throw a JS error at the site of the failure. This is the default.
{
"onerror": "log",
"resources": {
"./app/checked.js": {
"integrity": "sha384-SggXRQHwCG8g+DktYYzxkXRIkTiEYWBHqev0xnpCxYlqMBufKZHAHQM3/boDaI/0"
}
}
}
完整性检查#
¥Integrity checks
策略文件必须使用与与绝对 URL 关联的浏览器 完整性属性 兼容的子资源完整性字符串进行完整性检查。
¥Policy files must use integrity checks with Subresource Integrity strings compatible with the browser integrity attribute associated with absolute URLs.
当使用 require()
或 import
时,如果已指定策略清单,则检查加载中涉及的所有资源的完整性。如果资源与清单中列出的完整性不匹配,则会抛出错误。
¥When using require()
or import
all resources involved in loading are checked
for integrity if a policy manifest has been specified. If a resource does not
match the integrity listed in the manifest, an error will be thrown.
允许加载文件 checked.js
的示例策略文件:
¥An example policy file that would allow loading a file checked.js
:
{
"resources": {
"./app/checked.js": {
"integrity": "sha384-SggXRQHwCG8g+DktYYzxkXRIkTiEYWBHqev0xnpCxYlqMBufKZHAHQM3/boDaI/0"
}
}
}
策略清单中列出的每个资源都可以采用以下格式之一来确定其位置:
¥Each resource listed in the policy manifest can be of one the following formats to determine its location:
-
相对 URL 字符串 到清单中的资源,例如
./resource.js
、../resource.js
或/resource.js
。¥A relative-URL string to a resource from the manifest such as
./resource.js
,../resource.js
, or/resource.js
. -
资源的完整 URL 字符串,例如
file:///resource.js
。¥A complete URL string to a resource such as
file:///resource.js
.
当加载资源时,整个 URL 必须匹配,包括搜索参数和哈希片段。尝试加载 ./a.js
时不会使用 ./a.js?b
,反之亦然。
¥When loading resources the entire URL must match including search parameters
and hash fragment. ./a.js?b
will not be used when attempting to load
./a.js
and vice versa.
要生成完整性字符串,则可以使用 node -e 'process.stdout.write("sha256-");process.stdin.pipe(crypto.createHash("sha256").setEncoding("base64")).pipe(process.stdout)' < FILE
等脚本。
¥To generate integrity strings, a script such as
node -e 'process.stdout.write("sha256-");process.stdin.pipe(crypto.createHash("sha256").setEncoding("base64")).pipe(process.stdout)' < FILE
can be used.
完整性可以指定为布尔值 true
,以接受任何对本地开发有用的资源主体。不建议在生产中这样做,因为它会允许资源的意外更改被认为是有效的。
¥Integrity can be specified as the boolean value true
to accept any
body for the resource which can be useful for local development. It is not
recommended in production since it would allow unexpected alteration of
resources to be considered valid.
依赖重定向#
¥Dependency redirection
应用可能需要发布模块的补丁版本或阻止模块允许所有模块访问所有其他模块。可以通过拦截加载希望被替换的模块的尝试来使用重定向。
¥An application may need to ship patched versions of modules or to prevent modules from allowing all modules access to all other modules. Redirection can be used by intercepting attempts to load the modules wishing to be replaced.
{
"resources": {
"./app/checked.js": {
"dependencies": {
"fs": true,
"os": "./app/node_modules/alt-os",
"http": { "import": true }
}
}
}
}
依赖由请求的说明符字符串作为键,并且具有 true
、null
、指向要解析的模块的字符串或条件对象的值。
¥The dependencies are keyed by the requested specifier string and have values
of either true
, null
, a string pointing to a module to be resolved,
or a conditions object.
说明符字符串不执行任何搜索,并且必须与提供给 require()
或 import
的内容完全匹配,但规范化步骤除外。因此,如果策略使用多个不同的字符串指向同一个模块(例如排除扩展名),则可能需要多个说明符。
¥The specifier string does not perform any searching and must match exactly what
is provided to the require()
or import
except for a canonicalization step.
Therefore, multiple specifiers may be needed in the policy if it uses multiple
different strings to point to the same module (such as excluding the extension).
说明符字符串已规范化,但在用于匹配之前未解析,以便与导入映射具有某种兼容性,例如,如果资源 file:///C:/app/utils.js
从位于 file:///C:/app/policy.json
的策略中获得以下重定向:
¥Specifier strings are canonicalized but not resolved prior to be used for
matching in order to have some compatibility with import maps, for example if a
resource file:///C:/app/utils.js
was given the following redirection from a
policy located at file:///C:/app/policy.json
:
{
"resources": {
"file:///C:/app/utils.js": {
"dependencies": {
"./utils.js": "./utils-v2.js"
}
}
}
}
任何用于加载 file:///C:/app/utils.js
的说明符将被拦截并重定向到 file:///C:/app/utils-v2.js
,而不考虑使用绝对或相对说明符。但是,如果使用的说明符不是绝对或相对 URL 字符串,则不会被截取。所以,如果使用了 import('#utils')
之类的导入,则不会被拦截。
¥Any specifier used to load file:///C:/app/utils.js
would then be intercepted
and redirected to file:///C:/app/utils-v2.js
instead regardless of using an
absolute or relative specifier. However, if a specifier that is not an absolute
or relative URL string is used, it would not be intercepted. So, if an import
such as import('#utils')
was used, it would not be intercepted.
如果重定向的值为 true
,则将使用策略文件顶部的 "dependencies" 字段。如果策略文件顶部的字段是 true
,则使用默认节点搜索算法来查找模块。
¥If the value of the redirection is true
, a "dependencies" field at the top of
the policy file will be used. If that field at the top of the policy file is
true
the default node searching algorithms are used to find the module.
如果重定向的值是字符串,则相对于清单进行解析,然后立即使用而无需搜索。
¥If the value of the redirection is a string, it is resolved relative to the manifest and then immediately used without searching.
根据策略,任何尝试解析且未在依赖中列出的说明符字符串都会导致错误。
¥Any specifier string for which resolution is attempted and that is not listed in the dependencies results in an error according to the policy.
可以指定依赖映射的布尔值 true
以允许模块加载任何说明符而无需重定向。这对本地开发很有用,并且在生产中可能有一些有效的用途,但只有在审核模块以确保其行为有效后才应谨慎使用。
¥A boolean value of true
for the dependencies map can be specified to allow a
module to load any specifier without redirection. This can be useful for local
development and may have some valid usage in production, but should be used
only with care after auditing a module to ensure its behavior is valid.
与 package.json
中的 "exports"
类似,依赖也可以指定为包含条件的对象,这些条件分支如何加载依赖。在前面的示例中,当 "import"
条件是加载它的一部分时,允许 "http"
。
¥Similar to "exports"
in package.json
, dependencies can also be specified to
be objects containing conditions which branch how dependencies are loaded. In
the preceding example, "http"
is allowed when the "import"
condition is
part of loading it.
解析值的值 null
会导致解析失败。这可用于确保明确阻止某些类型的动态访问。
¥A value of null
for the resolved value causes the resolution to fail. This
can be used to ensure some kinds of dynamic access are explicitly prevented.
已解析模块位置的未知值会导致失败,但不能保证向前兼容。
¥Unknown values for the resolved module location cause failures but are not guaranteed to be forward compatible.
策略重定向的所有保证都在 保证 部分中指定。
¥All the guarantees for policy redirection are specified in the Guarantees section.
示例:补丁依赖#
¥Example: Patched dependency
重定向的依赖可以提供适合应用的衰减或修改功能。例如,通过封装原始记录有关函数持续时间的计时数据:
¥Redirected dependencies can provide attenuated or modified functionality as fits the application. For example, log data about timing of function durations by wrapping the original:
const original = require('fn');
module.exports = function fn(...args) {
console.time();
try {
return new.target ?
Reflect.construct(original, args) :
Reflect.apply(original, this, args);
} finally {
console.timeEnd();
}
};
作用域#
¥Scopes
使用清单的 "scopes"
字段一次设置多个资源的配置。"scopes"
字段的工作原理是按片段匹配资源。如果范围或资源包含 "cascade": true
,则将在其包含范围内搜索未知说明符。通过删除 特别计划 的段、保留尾随的 "/"
后缀以及删除查询和散列片段,递归地减少资源 URL,找到级联的包含范围。这导致 URL 最终减少到其来源。如果 URL 是非特殊的,则范围将由 URL 的来源定位。如果没有找到源的范围或在不透明源的情况下,可以使用协议字符串作为范围。如果没有找到 URL 协议的范围,将使用最终的空字符串 ""
范围。
¥Use the "scopes"
field of a manifest to set configuration for many resources
at once. The "scopes"
field works by matching resources by their segments.
If a scope or resource includes "cascade": true
, unknown specifiers will
be searched for in their containing scope. The containing scope for cascading
is found by recursively reducing the resource URL by removing segments for
special schemes, keeping trailing "/"
suffixes, and removing the query and
hash fragment. This leads to the eventual reduction of the URL to its origin.
If the URL is non-special the scope will be located by the URL's origin. If no
scope is found for the origin or in the case of opaque origins, a protocol
string can be used as a scope. If no scope is found for the URL's protocol, a
final empty string ""
scope will be used.
请注意,blob:
URL 从它们包含的路径中获取它们的来源,因此 "blob:https://nodejs.cn"
的范围将无效,因为没有 URL 可以具有 blob:https://nodejs.cn
的来源;以 blob:https://nodejs.cn/
开头的 URL 将使用 https://nodejs.cn
作为其来源,因此使用 https:
作为其协议范围。对于不透明的来源 blob:
URL,它们的协议范围将具有 blob:
,因为它们不采用来源。
¥Note, blob:
URLs adopt their origin from the path they contain, and so a scope
of "blob:https://nodejs.cn"
will have no effect since no URL can have an
origin of blob:https://nodejs.cn
; URLs starting with
blob:https://nodejs.cn/
will use https://nodejs.cn
for its origin and
thus https:
for its protocol scope. For opaque origin blob:
URLs they will
have blob:
for their protocol scope since they do not adopt origins.
示例#
¥Example
{
"scopes": {
"file:///C:/app/": {},
"file:": {},
"": {}
}
}
给定一个位于 file:///C:/app/bin/main.js
的文件,将按顺序检查以下范围:
¥Given a file located at file:///C:/app/bin/main.js
, the following scopes would
be checked in order:
"file:///C:/app/bin/"
这决定了 "file:///C:/app/bin/"
中所有基于文件的资源的策略。这不在策略的 "scopes"
字段中,将被跳过。将此范围添加到策略将导致它在 "file:///C:/app/"
范围之前使用。
¥This determines the policy for all file based resources within
"file:///C:/app/bin/"
. This is not in the "scopes"
field of the policy and
would be skipped. Adding this scope to the policy would cause it to be used
prior to the "file:///C:/app/"
scope.
"file:///C:/app/"
这决定了 "file:///C:/app/"
中所有基于文件的资源的策略。这是在策略的 "scopes"
字段中,它将确定 file:///C:/app/bin/main.js
资源的策略。如果范围有 "cascade": true
,则任何关于资源的不满意查询都将委托给 file:///C:/app/bin/main.js
、"file:"
的下一个相关范围。
¥This determines the policy for all file based resources within
"file:///C:/app/"
. This is in the "scopes"
field of the policy and it would
determine the policy for the resource at file:///C:/app/bin/main.js
. If the
scope has "cascade": true
, any unsatisfied queries about the resource would
delegate to the next relevant scope for file:///C:/app/bin/main.js
, "file:"
.
"file:///C:/"
这决定了 "file:///C:/"
中所有基于文件的资源的策略。这不在策略的 "scopes"
字段中,将被跳过。除非 "file:///C:/app/"
设置为级联或不在策略的 "scopes"
中,否则它不会用于 file:///C:/app/bin/main.js
。
¥This determines the policy for all file based resources within "file:///C:/"
.
This is not in the "scopes"
field of the policy and would be skipped. It would
not be used for file:///C:/app/bin/main.js
unless "file:///C:/app/"
is set
to cascade or is not in the "scopes"
of the policy.
"file:///"
这决定了 localhost
上所有基于文件的资源的策略。这不在策略的 "scopes"
字段中,将被跳过。除非 "file:///C:/"
设置为级联或不在策略的 "scopes"
中,否则它不会用于 file:///C:/app/bin/main.js
。
¥This determines the policy for all file based resources on the localhost
. This
is not in the "scopes"
field of the policy and would be skipped. It would not
be used for file:///C:/app/bin/main.js
unless "file:///C:/"
is set to
cascade or is not in the "scopes"
of the policy.
"file:"
这决定了所有基于文件的资源的策略。除非 "file:///"
设置为级联或不在策略的 "scopes"
中,否则它不会用于 file:///C:/app/bin/main.js
。
¥This determines the policy for all file based resources. It would not be used
for file:///C:/app/bin/main.js
unless "file:///"
is set to cascade or is not
in the "scopes"
of the policy.
""
这决定了所有资源的策略。除非 "file:"
设置为级联,否则它不会用于 file:///C:/app/bin/main.js
。
¥This determines the policy for all resources. It would not be used for
file:///C:/app/bin/main.js
unless "file:"
is set to cascade.
使用范围的完整性#
¥Integrity using scopes
在范围上将完整性设置为 true
会将清单中未找到的任何资源的完整性设置为 true
。
¥Setting an integrity to true
on a scope will set the integrity for any
resource not found in the manifest to true
.
在范围上将完整性设置为 null
会将清单中未找到的任何资源的完整性设置为匹配失败。
¥Setting an integrity to null
on a scope will set the integrity for any
resource not found in the manifest to fail matching.
不包括完整性与将完整性设置为 null
相同。
¥Not including an integrity is the same as setting the integrity to null
.
如果显式地设置了 "integrity"
,则将忽略用于完整性检查的 "cascade"
。
¥"cascade"
for integrity checks will be ignored if "integrity"
is explicitly
set.
以下示例允许加载任何文件:
¥The following example allows loading any file:
{
"scopes": {
"file:": {
"integrity": true
}
}
}
使用范围的依赖重定向#
¥Dependency redirection using scopes
以下示例将允许 ./app/
内的所有资源访问 fs
:
¥The following example, would allow access to fs
for all resources within
./app/
:
{
"resources": {
"./app/checked.js": {
"cascade": true,
"integrity": true
}
},
"scopes": {
"./app/": {
"dependencies": {
"fs": true
}
}
}
}
以下示例将允许访问 fs
的所有 data:
资源:
¥The following example, would allow access to fs
for all data:
resources:
{
"resources": {
"data:text/javascript,import('node:fs');": {
"cascade": true,
"integrity": true
}
},
"scopes": {
"data:": {
"dependencies": {
"fs": true
}
}
}
}
示例:导入映射模拟#
¥Example: import maps emulation
给定导入映射:
¥Given an import map:
{
"imports": {
"react": "./app/node_modules/react/index.js"
},
"scopes": {
"./ssr/": {
"react": "./app/node_modules/server-side-react/index.js"
}
}
}
{
"dependencies": true,
"scopes": {
"": {
"cascade": true,
"dependencies": {
"react": "./app/node_modules/react/index.js"
}
},
"./ssr/": {
"cascade": true,
"dependencies": {
"react": "./app/node_modules/server-side-react/index.js"
}
}
}
}
导入映射 假定你可以默认获取任何资源。这意味着策略顶层的 "dependencies"
应设置为 true
。策略要求选择加入,因为它启用了应用交叉链接的所有资源,这对许多场景没有意义。他们还假设任何给定的范围都可以访问其允许的依赖之上的任何范围;所有模拟导入映射的范围都必须设置 "cascade": true
。
¥Import maps assume you can get any resource by default. This means
"dependencies"
at the top level of the policy should be set to true
.
Policies require this to be opt-in since it enables all resources of the
application cross linkage which doesn't make sense for many scenarios. They also
assume any given scope has access to any scope above its allowed dependencies;
all scopes emulating import maps must set "cascade": true
.
导入映射的 "imports" 只有一个顶层范围。所以为了模拟 "imports"
使用 ""
范围。为了模拟 "scopes"
,使用 "scopes"
的方式与 "scopes"
在导入映射中的工作方式类似。
¥Import maps only have a single top level scope for their "imports". So for
emulating "imports"
use the ""
scope. For emulating "scopes"
use the
"scopes"
in a similar manner to how "scopes"
works in import maps.
注意事项:策略不使用字符串匹配来进行范围的各种查找。它们做 URL 遍历。这意味着像 blob:
和 data:
URL 之类的东西可能无法在两个系统之间完全互操作。例如导入映射可以通过在 /
字符上对 URL 进行分区来部分匹配 data:
或 blob:
URL,策略故意不能。对于 blob:
URL,导入映射范围不采用 blob:
URL 的来源。
¥Caveats: Policies do not use string matching for various finding of scope. They
do URL traversals. This means things like blob:
and data:
URLs might not be
entirely interoperable between the two systems. For example import maps can
partially match a data:
or blob:
URL by partitioning the URL on a /
character, policies intentionally cannot. For blob:
URLs import map scopes do
not adopt the origin of the blob:
URL.
此外,导入映射仅适用于 import
,因此可能需要向所有依赖映射添加 "import"
条件。
¥Additionally, import maps only work on import
so it may be desirable to add a
"import"
condition to all dependency mappings.
保证#
¥Guarantees
-
当使用
require()
、import()
或new Module()
加载模块时,这些策略保证文件完整性。¥The policies guarantee the file integrity when a module is loaded using
require()
,import()
ornew Module()
. -
重定向不会阻止通过直接访问
require.cache
等方式访问 API,从而允许访问已加载的模块。策略重定向只影响到require()
和import
的说明符。¥Redirection does not prevent access to APIs through means such as direct access to
require.cache
which allow access to loaded modules. Policy redirection only affects specifiers torequire()
andimport
. -
策略威胁模型中模块完整性的批准意味着一旦加载,它们就可以销毁甚至规避安全功能,因此环境/运行时强化是预期的。
¥The approval of the module integrity in policies threat model implies they are allowed to muck with and even circumvent security features once loaded so environmental/runtime hardening is expected.
基于进程的权限#
¥Process-based permissions
权限模型#
¥Permission Model
¥Stability: 1.1 - Active development
Node.js 权限模型是一种在执行期间限制对特定资源的访问的机制。API 存在于标志 --experimental-permission
之后,启用后将限制对所有可用权限的访问。
¥The Node.js Permission Model is a mechanism for restricting access to specific
resources during execution.
The API exists behind a flag --experimental-permission
which when enabled,
will restrict access to all available permissions.
可用权限由 --experimental-permission
标志记录。
¥The available permissions are documented by the --experimental-permission
flag.
使用 --experimental-permission
启动 Node.js 时,通过 fs
模块访问文件系统、生成进程、使用 node:worker_threads
、使用原生插件、使用 WASI 和启用运行时检查器的能力将受到限制。
¥When starting Node.js with --experimental-permission
,
the ability to access the file system through the fs
module, spawn processes,
use node:worker_threads
, use native addons, use WASI, and enable the runtime inspector
will be restricted.
$ node --experimental-permission index.js
node:internal/modules/cjs/loader:171
const result = internalModuleStat(filename);
^
Error: Access to this API has been restricted
at stat (node:internal/modules/cjs/loader:171:18)
at Module._findPath (node:internal/modules/cjs/loader:627:16)
at resolveMainPath (node:internal/modules/run_main:19:25)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:76:24)
at node:internal/main/run_main_module:23:47 {
code: 'ERR_ACCESS_DENIED',
permission: 'FileSystemRead',
resource: '/home/user/index.js'
}
允许访问生成进程和创建工作线程可以分别使用 --allow-child-process
和 --allow-worker
来完成。
¥Allowing access to spawning a process and creating worker threads can be done
using the --allow-child-process
and --allow-worker
respectively.
要在使用权限模型时允许原生插件,请使用 --allow-addons
标志。对于 WASI,请使用 --allow-wasi
标志。
¥To allow native addons when using permission model, use the --allow-addons
flag. For WASI, use the --allow-wasi
flag.
运行时 API#
¥Runtime API
通过 --experimental-permission
标志启用权限模型时,新属性 permission
将添加到 process
对象。此属性包含一个功能:
¥When enabling the Permission Model through the --experimental-permission
flag a new property permission
is added to the process
object.
This property contains one function:
permission.has(scope[, reference])
#
在运行时检查权限的 API 调用 (permission.has()
)
¥API call to check permissions at runtime (permission.has()
)
process.permission.has('fs.write'); // true
process.permission.has('fs.write', '/home/rafaelgss/protected-folder'); // true
process.permission.has('fs.read'); // true
process.permission.has('fs.read', '/home/rafaelgss/protected-folder'); // false
文件系统权限#
¥File System Permissions
默认情况下,权限模型通过 node:fs
模块限制对文件系统的访问。它不能保证用户无法通过其他方式(例如通过 node:sqlite
模块)访问文件系统。
¥The Permission Model, by default, restricts access to the file system through the node:fs
module.
It does not guarantee that users will not be able to access the file system through other means,
such as through the node:sqlite
module.
要允许访问文件系统,请使用 --allow-fs-read
和 --allow-fs-write
标志:
¥To allow access to the file system, use the --allow-fs-read
and
--allow-fs-write
flags:
$ node --experimental-permission --allow-fs-read=* --allow-fs-write=* index.js
Hello world!
(node:19836) ExperimentalWarning: Permission is an experimental feature
(Use `node --trace-warnings ...` to show where the warning was created)
两个标志的有效参数是:
¥The valid arguments for both flags are:
-
*
- 分别允许所有FileSystemRead
或FileSystemWrite
操作。¥
*
- To allow allFileSystemRead
orFileSystemWrite
operations, respectively. -
以逗号 (
,
) 分隔的路径分别仅允许匹配FileSystemRead
或FileSystemWrite
操作。¥Paths delimited by comma (
,
) to allow only matchingFileSystemRead
orFileSystemWrite
operations, respectively.
示例:
¥Example:
-
--allow-fs-read=*
- 它将允许所有FileSystemRead
操作。¥
--allow-fs-read=*
- It will allow allFileSystemRead
operations. -
--allow-fs-write=*
- 它将允许所有FileSystemWrite
操作。¥
--allow-fs-write=*
- It will allow allFileSystemWrite
operations. -
--allow-fs-write=/tmp/
- 它将允许FileSystemWrite
访问/tmp/
文件夹。¥
--allow-fs-write=/tmp/
- It will allowFileSystemWrite
access to the/tmp/
folder. -
--allow-fs-read=/tmp/ --allow-fs-read=/home/.gitignore
- 它允许FileSystemRead
访问/tmp/
文件夹和/home/.gitignore
路径。¥
--allow-fs-read=/tmp/ --allow-fs-read=/home/.gitignore
- It allowsFileSystemRead
access to the/tmp/
folder and the/home/.gitignore
path.
也支持通配符:
¥Wildcards are supported too:
-
--allow-fs-read=/home/test*
将允许读取与通配符匹配的所有内容。例如:/home/test/file1
或/home/test2
¥
--allow-fs-read=/home/test*
will allow read access to everything that matches the wildcard. e.g:/home/test/file1
or/home/test2
传递通配符 (*
) 后,所有后续字符都将被忽略。例如:/home/*.js
的工作方式与 /home/*
类似。
¥After passing a wildcard character (*
) all subsequent characters will
be ignored. For example: /home/*.js
will work similar to /home/*
.
初始化权限模型时,如果指定的目录存在,它将自动添加通配符 (*)。例如,如果 /home/test/files
存在,它将被视为 /home/test/files/*
。但是,如果目录不存在,则不会添加通配符,并且访问将仅限于 /home/test/files
。如果要允许访问尚不存在的文件夹,请确保明确包含通配符:/my-path/folder-do-not-exist/*
。
¥When the permission model is initialized, it will automatically add a wildcard
(*) if the specified directory exists. For example, if /home/test/files
exists, it will be treated as /home/test/files/*
. However, if the directory
does not exist, the wildcard will not be added, and access will be limited to
/home/test/files
. If you want to allow access to a folder that does not exist
yet, make sure to explicitly include the wildcard:
/my-path/folder-do-not-exist/*
.
权限模型约束#
¥Permission Model constraints
在使用此系统之前,你需要了解一些限制条件:
¥There are constraints you need to know before using this system:
-
该模型不会继承到子节点进程或工作线程。
¥The model does not inherit to a child node process or a worker thread.
-
使用权限模型时,以下功能将受到限制:
¥When using the Permission Model the following features will be restricted:
-
原生模块
¥Native modules
-
子进程
¥Child process
-
工作线程
¥Worker Threads
-
检查器协议
¥Inspector protocol
-
文件系统访问
¥File system access
-
WASI
-
-
权限模型是在 Node.js 环境搭建完成后初始化的。但是,某些标志(例如
--env-file
或--openssl-config
)被设计为在环境初始化之前读取文件。因此,此类标志不受权限模型规则的约束。这同样适用于可以通过v8.setFlagsFromString
在运行时设置的 V8 标志。¥The Permission Model is initialized after the Node.js environment is set up. However, certain flags such as
--env-file
or--openssl-config
are designed to read files before environment initialization. As a result, such flags are not subject to the rules of the Permission Model. The same applies for V8 flags that can be set via runtime throughv8.setFlagsFromString
. -
当启用权限模型时,无法在运行时请求 OpenSSL 引擎,从而影响内置的 crypto、https 和 tls 模块。
¥OpenSSL engines cannot be requested at runtime when the Permission Model is enabled, affecting the built-in crypto, https, and tls modules.
-
通过
node:fs
模块使用现有文件描述符会绕过权限模型。¥Using existing file descriptors via the
node:fs
module bypasses the Permission Model.
限制和已知问题#
¥Limitations and Known Issues
-
符号链接甚至会被跟踪到已授予访问权限的路径集之外的位置。相对符号链接可以允许访问任意文件和目录。在启用权限模型的情况下启动应用时,必须确保已授予访问权限的路径不包含相对符号链接。
¥Symbolic links will be followed even to locations outside of the set of paths that access has been granted to. Relative symbolic links may allow access to arbitrary files and directories. When starting applications with the permission model enabled, you must ensure that no paths to which access has been granted contain relative symbolic links.