安全最佳实践
¥Security Best Practices
意图
¥Intent
本文档旨在扩展当前的 威胁模型 并提供有关如何保护 Node.js 应用的广泛指南。
¥This document intends to extend the current threat model and provide extensive guidelines on how to secure a Node.js application.
文档内容
¥Document Content
-
最佳实践:一种简化的简明方法来查看最佳实践。我们可以使用 这个问题 或 本指南 作为起点。需要注意的是,本文档特定于 Node.js,如果你正在寻找更广泛的内容,请考虑 OSSF 最佳实践。
¥Best practices: A simplified condensed way to see the best practices. We can use this issue or this guideline as the starting point. It is important to note that this document is specific to Node.js, if you are looking for something broad, consider OSSF Best Practices.
-
攻击解释:用简单的英语说明和记录我们在威胁模型中提到的攻击的一些代码示例(如果可能)。
¥Attacks explained: illustrate and document in plain English with some code examples (if possible) of the attacks that we are mentioning in the threat model.
-
第三方库:定义威胁(域名抢注攻击、恶意包……)和有关 node 模块依赖的最佳实践等……
¥Third-Party Libraries: define threats (typosquatting attacks, malicious packages...) and best practices regarding node modules dependencies, etc...
威胁列表
¥Threat List
HTTP 服务器拒绝服务 (CWE-400)
¥Denial of Service of HTTP server (CWE-400)
这是一种攻击,由于应用处理传入 HTTP 请求的方式,应用无法用于其设计目的。这些请求不需要由恶意行为者故意制作:配置错误或存在缺陷的客户端也可能向服务器发送导致拒绝服务的请求模式。
¥This is an attack where the application becomes unavailable for the purpose it was designed due to the way it processes incoming HTTP requests. These requests need not be deliberately crafted by a malicious actor: a misconfigured or buggy client can also send a pattern of requests to the server that result in a denial of service.
HTTP 请求由 Node.js HTTP 服务器接收,并通过已注册的请求处理程序交给应用代码。服务器不解析请求主体的内容。因此,在将主体内容移交给请求处理程序后,由主体内容引起的任何 DoS 都不是 Node.js 本身的漏洞,因为正确处理它是应用代码的责任。
¥HTTP requests are received by the Node.js HTTP server and handed over to the application code via the registered request handler. The server does not parse the content of the request body. Therefore any DoS caused by the contents of the body after they are handed over to the request handler is not a vulnerability in Node.js itself, since it's the responsibility of the application code to handle it correctly.
确保 WebServer 正确处理套接字错误,例如,当创建服务器时没有错误处理程序,它将容易受到 DoS 攻击
¥Ensure that the WebServer handles socket errors properly, for instance, when a server is created without an error handler, it will be vulnerable to DoS
const net = require('node:net');
const server = net.createServer(function (socket) {
// socket.on('error', console.error) // this prevents the server to crash
socket.write('Echo server\r\n');
socket.pipe(socket);
});
server.listen(5000, '0.0.0.0');
如果执行了错误的请求,服务器可能会崩溃。
¥If a bad request is performed the server could crash.
Slowloris 就是一个非由请求内容引起的 DoS 攻击示例。在此攻击中,HTTP 请求发送缓慢且碎片化,一次发送一个片段。在完整请求交付之前,服务器将保留专用于正在进行的请求的资源。如果同时发送了足够多的此类请求,并发连接数很快就会达到最大值,从而导致拒绝服务。这就是攻击不依赖于请求的内容而是依赖于发送到服务器的请求的时间和模式的方式。
¥An example of a DoS attack that is not caused by the request's contents is Slowloris. In this attack, HTTP requests are sent slowly and fragmented, one fragment at a time. Until the full request is delivered, the server will keep resources dedicated to the ongoing request. If enough of these requests are sent at the same time, the amount of concurrent connections will soon reach its maximum resulting in a denial of service. This is how the attack depends not on the request's contents but on the timing and pattern of the requests being sent to the server.
缓解措施
¥Mitigations
-
使用反向代理接收并转发对 Node.js 应用的请求。反向代理可以提供缓存、负载平衡、IP 黑名单等,从而降低 DoS 攻击生效的可能性。
¥Use a reverse proxy to receive and forward requests to the Node.js application. Reverse proxies can provide caching, load balancing, IP blacklisting, etc. which reduce the probability of a DoS attack being effective.
-
正确配置服务器超时,以便可以丢弃空闲或请求到达太慢的连接。请参阅
http.Server
中的不同超时,特别是headersTimeout
、requestTimeout
、timeout
和keepAliveTimeout
。¥Correctly configure the server timeouts, so that connections that are idle or where requests are arriving too slowly can be dropped. See the different timeouts in
http.Server
, particularlyheadersTimeout
,requestTimeout
,timeout
, andkeepAliveTimeout
. -
限制每个主机和总共打开的套接字数量。请参阅 http 文档,特别是
agent.maxSockets
、agent.maxTotalSockets
、agent.maxFreeSockets
和server.maxRequestsPerSocket
。¥Limit the number of open sockets per host and in total. See the http docs, particularly
agent.maxSockets
,agent.maxTotalSockets
,agent.maxFreeSockets
andserver.maxRequestsPerSocket
.
DNS 重新绑定 (CWE-346)
¥DNS Rebinding (CWE-346)
这是一种可以针对使用 --inspect switch 启用调试检查器运行的 Node.js 应用的攻击。
¥This is an attack that can target Node.js applications being run with the debugging inspector enabled using the --inspect switch.
由于在 Web 浏览器中打开的网站可以触发 WebSocket 和 HTTP 请求,因此它们可以针对本地运行的调试检查器。这通常由现代浏览器实现的 同源策略 来阻止,它禁止脚本从不同来源访问资源(这意味着恶意网站无法读取从本地 IP 地址请求的数据)。
¥Since websites opened in a web browser can make WebSocket and HTTP requests, they can target the debugging inspector running locally. This is usually prevented by the same-origin policy implemented by modern browsers, which forbids scripts from reaching resources from different origins (meaning a malicious website cannot read data requested from a local IP address).
但是,通过 DNS 重新绑定,攻击者可以暂时控制其请求的来源,使其看起来好像来自本地 IP 地址。这是通过控制网站和用于解析其 IP 地址的 DNS 服务器来实现的。有关详细信息,请参阅 DNS 重新绑定 wiki。
¥However, through DNS rebinding, an attacker can temporarily control the origin for their requests so that they seem to originate from a local IP address. This is done by controlling both a website and the DNS server used to resolve its IP address. See DNS Rebinding wiki for more details.
缓解措施
¥Mitigations
-
通过将
process.on(‘SIGUSR1’, …)
监听器附加到 SIGUSR1 信号检查器来禁用它。¥Disable inspector on SIGUSR1 signal by attaching a
process.on(‘SIGUSR1’, …)
listener to it. -
不要在生产中运行检查器协议。
¥Do not run the inspector protocol in production.
向未经授权的行为者暴露敏感信息 (CWE-552)
¥Exposure of Sensitive Information to an Unauthorized Actor (CWE-552)
在包发布期间,当前目录中包含的所有文件和文件夹都会推送到 npm 注册表。
¥All the files and folders included in the current directory are pushed to the npm registry during the package publication.
有一些机制可以通过使用 .npmignore
和 .gitignore
定义阻止列表或在 package.json
中定义允许列表来控制此行为
¥There are some mechanisms to control this behavior by defining a blocklist with
.npmignore
and .gitignore
or by defining an allowlist in the package.json
缓解措施
¥Mitigations
-
使用
npm publish --dry-run
列出要发布的所有文件。确保在发布包之前检查内容。¥Using
npm publish --dry-run
to list all the files to publish. Ensure to review the content before publishing the package. -
创建和维护忽略文件(例如
.gitignore
和.npmignore
)也很重要。在这些文件中,你可以指定不应发布哪些文件/文件夹。package.json
中的 文件属性 允许逆操作 - 允许列表。¥It’s also important to create and maintain ignore files such as
.gitignore
and.npmignore
. Throughout these files, you can specify which files/folders should not be published. The files property inpackage.json
allows the inverse operation -- allowed list. -
如果发生暴露,请确保 取消发布包。
¥In case of an exposure, make sure to unpublish the package.
HTTP 请求走私 (CWE-444)
¥HTTP Request Smuggling (CWE-444)
这是一种涉及两个 HTTP 服务器(通常是代理和 Node.js 应用)的攻击。客户端发送 HTTP 请求,该请求首先通过前端服务器(代理),然后重定向到后端服务器(应用)。当前端和后端对模糊 HTTP 请求的解释不同时,攻击者可能会发送恶意消息,前端看不到该消息,但后端会看到该消息,从而有效地将其 "smuggling" 通过代理服务器。
¥This is an attack that involves two HTTP servers (usually a proxy and a Node.js application). A client sends an HTTP request that goes first through the front-end server (the proxy) and then is redirected to the back-end server (the application). When the front-end and back-end interpret ambiguous HTTP requests differently, there is potential for an attacker to send a malicious message that won't be seen by the front-end but will be seen by the back-end, effectively "smuggling" it past the proxy server.
有关更详细的描述和示例,请参阅 CWE-444。
¥See the CWE-444 for a more detailed description and examples.
由于此攻击依赖于 Node.js 对 HTTP 请求的解释方式与(任意)HTTP 服务器不同,因此成功的攻击可能是由于 Node.js、前端服务器或两者中的漏洞造成的。如果 Node.js 解释请求的方式与 HTTP 规范一致(参见 RFC7230),则它不被视为 Node.js 中的漏洞。
¥Since this attack depends on Node.js interpreting HTTP requests differently from an (arbitrary) HTTP server, a successful attack can be due to a vulnerability in Node.js, the front-end server, or both. If the way the request is interpreted by Node.js is consistent with the HTTP specification (see RFC7230), then it is not considered a vulnerability in Node.js.
缓解措施
¥Mitigations
-
创建 HTTP 服务器时,请勿使用
insecureHTTPParser
选项。¥Do not use the
insecureHTTPParser
option when creating a HTTP Server. -
配置前端服务器以规范化模糊请求。
¥Configure the front-end server to normalize ambiguous requests.
-
持续监控 Node.js 和所选前端服务器中的新 HTTP 请求走私漏洞。
¥Continuously monitor for new HTTP request smuggling vulnerabilities in both Node.js and the front-end server of choice.
-
端到端使用 HTTP/2,并尽可能禁用 HTTP 降级。
¥Use HTTP/2 end to end and disable HTTP downgrading if possible.
通过定时攻击泄露信息 (CWE-208)
¥Information Exposure through Timing Attacks (CWE-208)
这是一种允许攻击者通过例如测量应用响应请求所需的时间来了解潜在敏感信息的攻击。此攻击并非特定于 Node.js,可以针对几乎所有运行时。
¥This is an attack that allows the attacker to learn potentially sensitive information by, for example, measuring how long it takes for the application to respond to a request. This attack is not specific to Node.js and can target almost all runtimes.
只要应用在时间敏感操作(例如分支)中使用秘密,就有可能遭受攻击。考虑在典型应用中处理身份验证。以下是基本身份验证方法,包括电子邮件和密码作为凭据。用户信息是从用户从理想情况下的 DBMS 提供的输入中检索的。检索用户信息后,将密码与从数据库检索到的用户信息进行比较。使用内置字符串比较对于相同长度的值需要更长的时间。当以可接受的量运行时,此比较会不情愿地增加请求的响应时间。通过比较请求响应时间,攻击者可以在大量请求中猜测密码的长度和值。
¥The attack is possible whenever the application uses a secret in a timing-sensitive operation (e.g., branch). Consider handling authentication in a typical application. Here, a basic authentication method includes email and password as credentials. User information is retrieved from the input the user has supplied from ideally a DBMS. Upon retrieving user information, the password is compared with the user information retrieved from the database. Using the built-in string comparison takes a longer time for the same-length values. This comparison, when run for an acceptable amount unwillingly increases the response time of the request. By comparing the request response times, an attacker can guess the length and the value of the password in a large quantity of requests.
缓解措施
¥Mitigations
-
加密 API 公开了一个函数
timingSafeEqual
,使用恒定时间算法比较实际和预期的敏感值。¥The crypto API exposes a function
timingSafeEqual
to compare actual and expected sensitive values using a constant-time algorithm. -
对于密码比较,你可以使用原生加密模块上也提供的 scrypt。
¥For password comparison, you can use the scrypt available also on the native crypto module.
-
更一般地说,避免在可变时间操作中使用秘密。这包括在密钥上进行分支,并且当攻击者可以位于同一基础设施(例如,同一台云机器)上时,使用密钥作为内存索引。用 JavaScript 编写恒定时间代码很难(部分原因是 JIT)。对于加密应用,请使用内置加密 API 或 WebAssembly(对于未在原生实现的算法)。
¥More generally, avoid using secrets in variable-time operations. This includes branching on secrets and, when the attacker could be co-located on the same infrastructure (e.g., same cloud machine), using a secret as an index into memory. Writing constant-time code in JavaScript is hard (partly because of the JIT). For crypto applications, use the built-in crypto APIs or WebAssembly (for algorithms not implemented in natively).
恶意第三方模块 (CWE-1357)
¥Malicious Third-Party Modules (CWE-1357)
目前,在 Node.js 中,任何包都可以访问强大的资源,例如网络访问。此外,由于它们还可以访问文件系统,因此它们可以将任何数据发送到任何地方。
¥Currently, in Node.js, any package can access powerful resources such as network access. Furthermore, because they also have access to the file system, they can send any data anywhere.
所有运行到 node 进程的代码都可以使用 eval()
(或其等效项)加载和运行其他任意代码。所有具有文件系统写访问权限的代码都可以通过写入已加载的新文件或现有文件来实现相同的目的。
¥All code running into a node process has the ability to load and run additional
arbitrary code by using eval()
(or its equivalents).
All code with file system write access may achieve the same thing by writing to
new or existing files that are loaded.
Node.js 有一个实验性的 ¹ 策略机制,用于将加载的资源声明为不受信任或受信任。但是,默认情况下不启用此策略。请务必固定依赖版本并使用常见工作流或 npm 脚本运行自动检查漏洞。在安装包之前,请确保此包得到维护并包含你期望的所有内容。小心,GitHub 源代码并不总是与已发布的代码相同,请在 node_modules 中验证它。
¥Node.js has an experimental¹ policy mechanism to declare the loaded resource as untrusted or trusted. However, this policy is not enabled by default. Be sure to pin dependency versions and run automatic checks for vulnerabilities using common workflows or npm scripts. Before installing a package make sure that this package is maintained and includes all the content you expected. Be careful, the GitHub source code is not always the same as the published one, validate it in the node_modules.
供应链攻击
¥Supply chain attacks
当 Node.js 应用的一个依赖(直接或传递)受到损害时,就会发生对它的供应链攻击。这可能是由于应用对依赖的规范过于松懈(允许不必要的更新)和/或规范中的常见拼写错误(易受 typosquatting 攻击)而发生的。
¥A supply chain attack on a Node.js application happens when one of its dependencies (either direct or transitive) are compromised. This can happen either due to the application being too lax on the specification of the dependencies (allowing for unwanted updates) and/or common typos in the specification (vulnerable to typosquatting).
控制上游包的攻击者可以发布包含恶意代码的新版本。如果 Node.js 应用依赖于该包,但未严格确定哪个版本可以安全使用,则该包可能会自动更新为最新的恶意版本,从而危害应用。
¥An attacker who takes control of an upstream package can publish a new version with malicious code in it. If a Node.js application depends on that package without being strict on which version is safe to use, the package can be automatically updated to the latest malicious version, compromising the application.
package.json
文件中指定的依赖可以具有确切的版本号或范围。但是,当将依赖固定到确切版本时,其传递依赖本身不会被固定。这仍然使应用容易受到不需要的/意外的更新。
¥Dependencies specified in the package.json
file can have an exact version number
or a range. However, when pinning a dependency to an exact version, its
transitive dependencies are not themselves pinned.
This still leaves the application vulnerable to unwanted/unexpected updates.
可能的攻击媒介:
¥Possible attack vectors:
-
域名抢注攻击
¥Typosquatting attacks
-
锁定文件中毒
¥Lockfile poisoning
-
受损的维护者
¥Compromised maintainers
-
恶意包
¥Malicious Packages
-
依赖混淆
¥Dependency Confusions
缓解措施
¥Mitigations
-
使用
--ignore-scripts
防止 npm 执行任意脚本¥Prevent npm from executing arbitrary scripts with
--ignore-scripts
-
此外,你可以使用
npm config set ignore-scripts true
全局禁用它¥Additionally, you can disable it globally with
npm config set ignore-scripts true
-
-
将依赖版本固定到特定的不可变版本,而不是范围或可变源的版本。
¥Pin dependency versions to a specific immutable version, not a version that is a range or from a mutable source.
-
使用锁定文件,它可以固定每个依赖(直接和传递)。
¥Use lockfiles, which pin every dependency (direct and transitive).
-
使用 锁文件中毒的缓解措施。
-
-
使用 CI 自动检查新漏洞,使用 [
npm-audit
][npm-audit
] 等工具。¥Automate checks for new vulnerabilities using CI, with tools like [
npm-audit
][]. -
使用
npm ci
而不是npm install
。这会强制执行锁定文件,以便它与 package.json 文件之间的不一致会导致错误(而不是默默忽略锁定文件而支持 package.json)。¥Use
npm ci
instead ofnpm install
. This enforces the lockfile so that inconsistencies between it and the package.json file causes an error (instead of silently ignoring the lockfile in favor of package.json). -
仔细检查 package.json 文件中依赖名称中的错误/拼写错误。
¥Carefully check the package.json file for errors/typos in the names of the dependencies.
内存访问冲突 (CWE-284)
¥Memory Access Violation (CWE-284)
基于内存或基于堆的攻击取决于内存管理错误和可利用的内存分配器的组合。与所有运行时一样,如果你的项目在共享机器上运行,Node.js 很容易受到这些攻击。使用安全堆对于防止由于指针溢出和欠载而导致敏感信息泄露很有用。
¥Memory-based or heap-based attacks depend on a combination of memory management errors and an exploitable memory allocator. Like all runtimes, Node.js is vulnerable to these attacks if your projects run on a shared machine. Using a secure heap is useful for preventing sensitive information from leaking due to pointer overruns and underruns.
不幸的是,Windows 上没有安全堆。可以在 Node.js 安全堆文档 上找到更多信息。
¥Unfortunately, a secure heap is not available on Windows. More information can be found on Node.js secure-heap documentation.
缓解措施
¥Mitigations
-
根据你的应用使用
--secure-heap=n
,其中 n 是分配的最大字节大小。¥Use
--secure-heap=n
depending on your application where n is the allocated maximum byte size. -
不要在共享机器上运行你的生产应用。
¥Do not run your production app on a shared machine.
Monkey Patching (CWE-349)
Monkey patching 是指在运行时修改属性,旨在改变现有行为。示例:
¥Monkey patching refers to the modification of properties in runtime aiming to change the existing behavior. Example:
// eslint-disable-next-line no-extend-native
Array.prototype.push = function (item) {
// overriding the global [].push
};
缓解措施
¥Mitigations
--frozen-intrinsics
标志启用实验性 ¹ 冻结内在函数,这意味着所有内置的 JavaScript 对象和函数都被递归冻结。因此,以下代码片段不会覆盖 Array.prototype.push
的默认行为
¥The --frozen-intrinsics
flag enables experimental¹
frozen intrinsics, which means all the built-in JavaScript objects and functions
are recursively frozen.
Therefore, the following snippet will not override the default behavior of
Array.prototype.push
// eslint-disable-next-line no-extend-native
Array.prototype.push = function (item) {
// overriding the global [].push
};
// Uncaught:
// TypeError <Object <Object <[Object: null prototype] {}>>>:
// Cannot assign to read only property 'push' of object ''
但是,值得一提的是,你仍然可以定义新的全局变量并使用 globalThis
替换现有的全局变量
¥However, it’s important to mention you can still define new globals and replace
existing globals using globalThis
> globalThis.foo = 3; foo; // you can still define new globals
3
> globalThis.Array = 4; Array; // However, you can also replace existing globals
4
因此,Object.freeze(globalThis)
可用于保证不会替换任何全局变量。
¥Therefore, Object.freeze(globalThis)
can be used to guarantee no globals will
be replaced.
原型污染攻击 (CWE-1321)
¥Prototype Pollution Attacks (CWE-1321)
原型污染是指通过滥用 _proto、_constructor、prototype 和从内置原型继承的其他属性来修改或将属性注入 Javascript 语言项目的可能性。
¥Prototype pollution refers to the possibility of modifying or injecting properties into Javascript language items by abusing the usage of _proto, _constructor, prototype, and other properties inherited from built-in prototypes.
const a = { a: 1, b: 2 };
const data = JSON.parse('{"__proto__": { "polluted": true}}');
const c = Object.assign({}, a, data);
console.log(c.polluted); // true
// Potential DoS
const data2 = JSON.parse('{"__proto__": null}');
const d = Object.assign(a, data2);
d.hasOwnProperty('b'); // Uncaught TypeError: d.hasOwnProperty is not a function
这是一个从 JavaScript 语言继承的潜在漏洞。
¥This is a potential vulnerability inherited from the JavaScript language.
示例:
¥Examples:
-
CVE-2022-21824(Node.js)
-
CVE-2018-3721(第三方库:Lodash)
¥CVE-2018-3721 (3rd Party library: Lodash)
缓解措施
¥Mitigations
-
避免 不安全的递归合并,参见 CVE-2018-16487。
¥Avoid insecure recursive merges, see CVE-2018-16487.
-
为外部/不受信任的请求实现 JSON Schema 验证。
¥Implement JSON Schema validations for external/untrusted requests.
-
使用
Object.create(null)
创建没有原型的对象。¥Create Objects without prototype by using
Object.create(null)
. -
冻结原型:
Object.freeze(MyObject.prototype)
。¥Freezing the prototype:
Object.freeze(MyObject.prototype)
. -
使用
--disable-proto
标志禁用Object.prototype.__proto__
属性。¥Disable the
Object.prototype.__proto__
property using--disable-proto
flag. -
检查属性是否直接存在于对象上,而不是使用
Object.hasOwn(obj, keyFromObj)
从原型中存在。¥Check that the property exists directly on the object, not from the prototype using
Object.hasOwn(obj, keyFromObj)
. -
避免使用来自
Object.prototype
的方法。¥Avoid using methods from
Object.prototype
.
不受控制的搜索路径元素 (CWE-427)
¥Uncontrolled Search Path Element (CWE-427)
Node.js 按照 模块解析算法 加载模块。因此,它假定请求模块(require)的目录是受信任的。
¥Node.js loads modules following the Module Resolution Algorithm. Therefore, it assumes the directory in which a module is requested (require) is trusted.
这意味着预期以下应用行为。假设以下目录结构:
¥By that, it means the following application behavior is expected. Assuming the following directory structure:
-
app/
-
server.js
-
auth.js
-
auth
-
如果 server.js 使用 require('./auth')
,它将遵循模块解析算法并加载 auth 而不是 auth.js。
¥If server.js uses require('./auth')
it will follow the module resolution
algorithm and load auth instead of auth.js.
缓解措施
¥Mitigations
使用实验性的 ¹ 具有完整性检查的策略机制 可以避免上述威胁。对于上面描述的目录,可以使用以下 policy.json
¥Using the experimental¹
policy mechanism with integrity checking can avoid the above threat.
For the directory described above, one can use the following policy.json
{
"resources": {
"./app/auth.js": {
"integrity": "sha256-iuGZ6SFVFpMuHUcJciQTIKpIyaQVigMZlvg9Lx66HV8="
},
"./app/server.js": {
"dependencies": {
"./auth": "./app/auth.js"
},
"integrity": "sha256-NPtLCQ0ntPPWgfVEgX46ryTNpdvTWdQPoZO3kHo0bKI="
}
}
}
因此,在需要 auth 模块时,系统将验证完整性,如果与预期不匹配,则抛出错误。
¥Therefore, when requiring the auth module, the system will validate the integrity and throw an error if doesn’t match the expected one.
» node --experimental-policy=policy.json app/server.js
node:internal/policy/sri:65
throw new ERR_SRI_PARSE(str, str[prevIndex], prevIndex);
^
SyntaxError [ERR_SRI_PARSE]: Subresource Integrity string "sha256-iuGZ6SFVFpMuHUcJciQTIKpIyaQVigMZlvg9Lx66HV8=%" had an unexpected "%" at position 51
at new NodeError (node:internal/errors:393:5)
at Object.parse (node:internal/policy/sri:65:13)
at processEntry (node:internal/policy/manifest:581:38)
at Manifest.assertIntegrity (node:internal/policy/manifest:588:32)
at Module._compile (node:internal/modules/cjs/loader:1119:21)
at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
at Module.load (node:internal/modules/cjs/loader:1037:32)
at Module._load (node:internal/modules/cjs/loader:878:12)
at Module.require (node:internal/modules/cjs/loader:1061:19)
at require (node:internal/modules/cjs/helpers:99:18) {
code: 'ERR_SRI_PARSE'
}
注意,始终建议使用 --policy-integrity
来避免策略突变。
¥Note, it's always recommended the use of --policy-integrity
to avoid policy mutations.
生产中的实验性功能
¥Experimental Features in Production
不建议在生产中使用实验性功能。实验性功能可能会在需要时遭受重大更改,并且其功能不稳定。尽管如此,我们非常感谢你的反馈。
¥The use of experimental features in production isn't recommended. Experimental features can suffer breaking changes if needed, and their functionality isn't securely stable. Although, feedback is highly appreciated.
OpenSSF 工具
¥OpenSSF Tools
OpenSSF 正在领导几个非常有用的计划,特别是如果你计划发布 npm 包。这些举措包括:
¥The OpenSSF is leading several initiatives that can be very useful, especially if you plan to publish an npm package. These initiatives include:
-
OpenSSF 记分卡 Scorecard 使用一系列自动安全风险检查来评估开源项目。你可以使用它来主动评估代码库中的漏洞和依赖,并做出有关接受漏洞的明智决策。
¥OpenSSF Scorecard Scorecard evaluates open source projects using a series of automated security risk checks. You can use it to proactively assess vulnerabilities and dependencies in your code base and make informed decisions about accepting vulnerabilities.
-
OpenSSF 最佳实践徽章计划 项目可以通过描述它们如何遵守每个最佳实践来自愿进行自我认证。这将生成一个可以添加到项目中的徽章。
¥OpenSSF Best Practices Badge Program Projects can voluntarily self-certify by describing how they comply with each best practice. This will generate a badge that can be added to the project.