一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

如何防范攻击者利用Object.setPrototypeOf恶意修改核心内置对象原型链进而强行绕过沙箱文件读写控制漏洞

时间:2026-07-01 11:16:46 编辑:袖梨 来源:一聚教程网

防范原型污染攻击的关键在于切断污染入口、物理隔离执行环境、冻结不可信行为路径:启动即冻结Object.prototype等核心原型,禁用Object.setPrototypeOf等危险API,使用Object.create(null)构建无原型对象,并结合进程级隔离与运行时监控。

防范攻击者利用 Object.setPrototypeOf 恶意篡改内置对象(如 Object.prototypeFunction.prototype)来绕过沙箱的文件读写控制,关键在于**切断污染入口、物理隔离执行环境、冻结不可信行为路径**。这类攻击常见于 Node.js 沙箱(如 vm 模块)或浏览器中嵌入第三方 SDK 的场景,一旦原型被污染,后续所有对象都会继承恶意方法(例如伪造 fs.readFile 返回值、劫持 require 加载逻辑),导致沙箱形同虚设。

启动即冻结核心原型链

在沙箱初始化完成、任何用户脚本执行前,立即冻结所有基础原型:

  • 执行 Object.freeze(Object.prototype)Object.freeze(Function.prototype)Object.freeze(Array.prototype) —— 这能阻止新增/修改/删除属性,包括 __proto__constructor
  • 若运行在 Node.js,配合启动参数 --disable-proto=throw,让任何对 __proto__ 的赋值直接抛错,而非静默失败
  • 注意:冻结必须早于任何第三方代码(包括 polyfill、SDK 初始化脚本),建议放在沙箱上下文创建后的第一行

禁用危险 API 并重写关键方法

仅靠冻结不够,还需主动封禁可被滥用的原生能力:

  • 在沙箱上下文中,将 Object.setPrototypeOf 替换为无操作函数:Object.setPrototypeOf = () => { throw new Error('setPrototypeOf disabled in sandbox'); };
  • 同时覆盖 Object.__proto__ 的 setter(如果环境支持):Object.defineProperty(Object.prototype, '__proto__', { set: () => { throw new Error('__proto__ assignment blocked'); } });
  • Function.prototype.bindReflect.setPrototypeOf 等间接入口也做同样处理,避免绕过

使用无原型对象构建沙箱边界

沙箱内部用于通信、配置、权限校验的对象,一律不用 {},改用更干净的基底:

  • 创建权限白名单表:const permissions = Object.create(null); permissions['fs.readFile'] = true;
  • 接收用户输入后,用 Object.prototype.hasOwnProperty.call(permissions, key) 判断是否允许调用,避免因原型污染导致误判
  • 所有插件注册、API 注入、路由映射等中间结构,均采用 Object.create(null),从源头消除原型链查找依赖

沙箱进程级隔离与运行时监控

对于高敏感场景(如云函数、低代码平台),需超越 JS 层防护:

  • Node.js 中优先选用 vm2 而非原生 vm,并启用其 timeoutmemoryLimit 限制,防止长时间运行绕过检测
  • 对沙箱子进程启用 seccomp-bpf 或容器级 syscall 过滤,禁止 openatread 等系统调用,即使原型被污染也无法真正触发文件操作
  • 沙箱启动后立即注入检测逻辑:if ({}.toString !== Object.prototype.toString) throw new Error('Prototype polluted');,发现异常立刻终止上下文

不复杂但容易忽略——真正的防护不是等攻击发生再打补丁,而是在沙箱诞生那一刻,就让它运行在一个“没有原型可被污染”的干净世界里。

热门栏目