Node.js Permission Model 怎样限制运行时文件访问
来源:17golang原创
时间:2026-10-29 02:18:51 257浏览 收藏
如果一个 Node.js 程序只需要读配置、写缓存,却能顺手访问进程所在机器上的其他文件,可以用 Permission Model 把运行时文件访问收窄到明确目录。官方入口:https://nodejs.org/api/permissions.html。
核心做法是用 --permission 开启默认拒绝,再分别用 --allow-fs-read 和 --allow-fs-write 授权路径。它更像防止可信代码误操作的“安全带”,不是用来承诺恶意代码绝对无法绕过的完整沙箱。
一、先理解 --permission 的默认文件访问边界
启动 Node.js 时加入 --permission,文件系统访问会进入权限检查。应用的入口文件会自动加入允许读取列表,所以 node --permission app.js 可以先加载 app.js;除此之外,代码读取未授权文件时会得到 ERR_ACCESS_DENIED。
这个默认值很重要:它不是“所有文件都能读、只限制写入”,而是先限制文件系统,再按任务补充授权。网络、子进程、Worker、原生插件、WASI、FFI 和 Inspector 等能力也会受到 Permission Model 影响,本文只展开文件读写。
二、用两个参数分别授权读取和写入
假设程序需要读取 ./config 下的配置,并把运行数据写入 ./data,启动命令可以写成:
# 只开放配置目录的读取和数据目录的写入 node --permission \ --allow-fs-read=./config \ --allow-fs-write=./data \ app.js
--allow-fs-read 和 --allow-fs-write 是两套独立范围:能读不代表能写,能写也不代表能读。路径可以使用相对当前工作目录的路径、绝对路径或 *;例如 --allow-fs-write=/tmp/ 只把写入范围交给该目录。生产启动脚本应优先写出实际目录,而不是直接使用全量通配符。
如果程序确实要访问一个尚不存在的目录,路径末尾应显式带上通配符,例如 --allow-fs-read=/srv/app/cache/*;Node.js 文档说明,对于已经存在的目录,初始化时可能自动补成目录通配范围,而不存在的目录不会自动补这个通配符。

三、把权限清单放进配置文件
命令行参数较多时,可以使用 --config-file 读取 Node.js 配置文件。权限项放在顶层 permission 对象中:
{
"permission": {
"allow-fs-read": ["./config"],
"allow-fs-write": ["./data"],
"allow-child-process": false,
"allow-worker": false,
"allow-net": false
}
}
保存为 node.config.json 后,用下面的命令启动:
# 配置文件中的 permission 节点会自动启用权限模型 node --config-file=node.config.json app.js
JSON 不能写注释,因此字段旁边的说明要放在文档或配置说明里;不要为了注释破坏 JSON 格式。配置文件的好处是可以把读写目录和其他能力开关一起提交审查,减少启动脚本被多处复制后出现权限漂移。

四、权限收窄后最容易忽略的边界
第一,--permission 不是恶意代码沙箱。官方文档明确 Node.js 信任被要求执行的代码,Permission Model 主要用于避免可信代码意外改文件或使用未显式授予的资源。
第二,符号链接需要单独检查。文档提示,已授权路径中的相对符号链接可能指向授权目录之外的位置;给应用开放目录前,要确认目录里没有把访问范围引向其他位置的相对链接。
第三,已经打开的文件描述符、网络连接或子进程不会因为后续权限变化自动关闭。运行时 API process.permission.drop() 只能影响未来的权限检查,资源生命周期仍要由应用自己关闭或终止。
最后,用 --permission-audit 可以先观察哪些权限检查会被触发而不拒绝访问,再把整理后的最小目录清单切换到 --permission。判断配置是否合适时,重点看“程序实际需要读写哪些目录”,不要把整个工作目录一股脑授权。
常见问题
为什么入口文件能读,旁边的 JSON 却读不到?入口文件会被自动加入允许读取列表,其他文件仍需通过 --allow-fs-read 或配置文件授权。
只允许写入目录时是否也要允许读取?读写是分开的。如果程序在写入前还要读取旧文件、读取目录内容或读取配置,就要单独授予读取范围。
能不能把 Permission Model 当作执行不可信脚本的隔离层?不能。它适合减少可信应用的意外资源访问;面对恶意代码,还需要操作系统级隔离和独立运行身份等边界。
总结:先用 --permission 把文件访问设为默认拒绝,再按“配置只读、数据可写”的任务拆分授权,最后用配置文件固定清单并检查符号链接、已打开资源和模型自身限制。
-
482 收藏
-
339 收藏
-
388 收藏
-
253 收藏
-
182 收藏
-
123 收藏
-
125 收藏
-
170 收藏
-
331 收藏
-
307 收藏
-
161 收藏
-
344 收藏
-
130 收藏
-
416 收藏
-
497 收藏
-
284 收藏
-
123 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习