
node.js v20引入了实验性权限模型,旨在增强应用安全性。启用该模型需使用--experimental-permission标志,此时所有资源访问默认受限。文章将详细介绍如何启用权限模型、配置文件系统读写权限(包括通配符和特定路径),并解析typeerror: cannot read properties of undefined和err_access_denied等常见错误及其解决方案,帮助开发者有效管理node.js应用的资源访问。
Node.js v20及更高版本引入了一个实验性的权限模型,其核心目标是为应用程序提供更细粒度的资源访问控制。这使得开发者能够明确指定其Node.js进程可以访问哪些文件、网络资源或其他API,从而显著提升应用的安全性,尤其是在处理不受信任的代码或构建沙箱环境时。该模型通过process.permission API提供运行时权限检查能力。
要使用Node.js的权限模型,必须在启动Node.js进程时显式启用一个命令行标志。
通过在运行命令中添加--experimental-permission标志来启用权限模型:
node --experimental-permission your-app.js
重要提示:当--experimental-permission标志被启用时,Node.js进程将默认拒绝所有权限,除非显式授权。
如果在没有启用--experimental-permission标志的情况下尝试访问process.permission对象,将会遇到TypeError。这是因为process.permission对象仅在权限模型被激活时才存在。
示例代码 (app.js):
// app.js
console.log(process.permission.has("fs.read"));未启用权限模型时的运行与错误:
$ node app.js
错误输出:
console.log(process.permission.has("fs.read"));
^
TypeError: Cannot read properties of undefined (reading 'has')
at file:///home/stanley/example-app/app.js:1:32
# ... (rest of stack trace)解析:此错误表明process.permission在当前上下文中是undefined,因此无法调用其has方法。解决方案是务必在运行Node.js程序时加上--experimental-permission标志。
一旦权限模型被启用,Node.js进程将默认受到严格限制。为了允许应用程序执行特定的操作,例如文件读写,需要使用特定的--allow-*标志来授予权限。
Node.js提供了--allow-fs-read和--allow-fs-write标志来控制文件系统的访问。
授予所有文件系统读权限: 使用--allow-fs-read=*可以允许进程读取任何文件。
授予所有文件系统写权限: 使用--allow-fs-write=*可以允许进程写入任何文件。
授予特定文件或目录的权限: 您可以指定一个逗号分隔的绝对路径列表,以限制对特定文件或目录的访问。 例如:--allow-fs-read=/path/to/file1,/path/to/directory2
重要提示:在指定特定路径时,必须使用绝对路径。相对路径当前不受支持,使用相对路径会导致权限检查失败。
当权限模型启用后,如果尝试执行一个未被明确授权的操作,Node.js将抛出ERR_ACCESS_DENIED错误。
示例场景:启用权限模型但未授予文件系统读权限。
$ node --experimental-permission app.js
错误输出:
node:internal/modules/cjs/loader:179
const result = internalModuleStat(filename);
^
Error: Access to this API has been restricted
at stat (node:internal/modules/cjs/loader:179:18)
# ... (rest of stack trace)
{
code: 'ERR_ACCESS_DENIED',
permission: 'FileSystemRead',
resource: '/home/stanley/example_app/app.js'
}解析:此错误清晰地表明,当前进程没有执行FileSystemRead操作的权限,并且尝试访问的资源是/home/stanley/example_app/app.js。
让我们通过一个具体的例子来演示如何结合使用权限模型和文件系统权限标志。
首先,创建两个文件:index.js(主程序)和 a.json(将被读取的数据)。
a.json:
{
"name": "lin"
}index.js:
const fs = require('fs');
const path = require('path');
// 检查当前进程是否具有文件系统读写权限
console.log('Has fs.read permission?', process.permission.has("fs.read"));
console.log('Has fs.write permission?', process.permission.has("fs.write"));
// 尝试读取 a.json
try {
const jsonData = fs.readFileSync(path.resolve(__dirname, './a.json'), 'utf-8');
console.log('JSON content:', jsonData);
} catch (error) {
console.error('Error reading a.json:', error.message);
}
// 尝试写入 b.json
try {
fs.writeFileSync(path.resolve(__dirname, './b.json'), JSON.stringify({ status: 'ok' }));
console.log('b.json written successfully.');
} catch (error) {
console.error('Error writing b.json:', error.message);
}现在,我们运行index.js,只授予所有文件系统读权限,但不授予写权限:
node --experimental-permission --allow-fs-read=* index.js
预期输出:
Has fs.read permission? true
Has fs.write permission? false
JSON content: {
"name": "lin"
}
Error writing b.json: Access to this API has been restricted分析:
假设我们只想允许index.js读取a.json和index.js本身,同时不授予写权限。 首先,获取a.json和index.js的绝对路径(请根据您的实际环境修改):
# 假设您的文件位于 /home/user/nodejs-app/
# 实际运行时请替换为您的绝对路径
NODE_APP_PATH=$(pwd)/index.js
A_JSON_PATH=$(pwd)/a.json
node --experimental-permission \
--allow-fs-read=${A_JSON_PATH},${NODE_APP_PATH} \
index.js预期输出(与上述类似,因为写权限仍未授予):
Has fs.read permission? true
Has fs.write permission? false
JSON content: {
"name": "lin"
}
Error writing b.json: Access to this API has been restricted分析:即使我们只指定了a.json和index.js的读权限,process.permission.has("fs.read")仍然返回true,因为它检查的是通用的fs.read能力。如果尝试读取未授权的文件,则会抛出ERR_ACCESS_DENIED。fs.writeFileSync依然失败,因为没有授予写权限。
通过理解和正确配置Node.js权限模型,开发者可以构建更安全、更健壮的Node.js应用程序,有效抵御潜在的恶意行为或意外的资源访问。随着该模型的不断成熟,它将成为Node.js生态系统中一个不可或缺的安全特性。
以上就是Node.js 实验性权限模型:启用、配置与常见错误解析的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号