原型链污染

原型链污染(Prototype Pollution)是一种针对 JavaScript 应用的安全漏洞,攻击者通过操纵对象的原型链,向基础对象(如 Object.prototype)注入恶意属性,从而影响整个应用程序的行为。以下是详细解析:


核心原理

  1. JavaScript 原型链机制

    • 每个对象都有隐式原型 __proto__(或通过 Object.getPrototypeOf() 访问),指向其构造函数的原型对象。
    • 访问对象属性时,若自身不存在,会沿原型链向上查找(直到 Object.prototype)。
    • 修改原型对象的属性会影响所有继承该原型的对象。
  2. 污染触发条件

    • 当应用递归合并 用户输入的 JSON 数据(如 Object.assign() 或自定义 merge 函数)。
    • 通过路径赋值 动态设置属性(如 obj[a][b] = value)。
    • 攻击者构造包含 __proto__constructor/prototype 的恶意 payload。

攻击示例

场景1:递归合并对象
javascript 复制代码
function merge(target, source) {
  for (const key in source) {
    if (typeof source[key] === 'object') {
      if (!target[key]) target[key] = {};
      merge(target[key], source[key]); // 递归合并
    } else {
      target[key] = source[key]; // 直接赋值
    }
  }
}

const userInput = JSON.parse('{"__proto__": {"isAdmin": true}}');
merge({}, userInput); // 污染 Object.prototype

// 验证
const obj = {};
console.log(obj.isAdmin); // true!所有对象继承恶意属性
场景2:路径赋值
javascript 复制代码
function setValue(obj, path, value) {
  const keys = path.split('.');
  let current = obj;
  for (let i = 0; i < keys.length - 1; i++) {
    if (!current[keys[i]]) current[keys[i]] = {};
    current = current[keys[i]];
  }
  current[keys[keys.length - 1]] = value;
}

// 攻击者输入路径 "__proto__.isAdmin" 和值 true
setValue({}, "__proto__.isAdmin", true);

// 验证
console.log(({}).isAdmin); // true

危害

  1. 权限提升 :添加 isAdmin: true 属性绕过身份检查。

  2. 拒绝服务(DoS) :覆盖 toString() 等方法导致应用崩溃。

  3. 远程代码执行(RCE) :结合其他漏洞(如模板注入)执行任意代码。

    javascript 复制代码
    // 若应用使用 eval 或类似功能
    Object.prototype.shell = "require('child_process').exec('rm -rf /')";

防御措施

  1. 避免原型属性操作

    • 使用 Object.create(null) 创建无原型的对象。

    • 检查属性名是否为 __proto__constructorprototype

      javascript 复制代码
      if (key.includes("__proto__") || key.includes("constructor")) return;
  2. 安全合并对象

    • 使用 Object.assign()(浅拷贝,不递归)替代自定义 merge。
    • 使用三方库如 lodash.merge(其新版已修复污染问题)。
  3. 冻结原型

    javascript 复制代码
    Object.freeze(Object.prototype); // 禁止修改原型
  4. 使用 Map 替代 ObjectMap 不受原型链影响。

  5. 输入过滤

    • 对用户输入的 JSON 数据过滤敏感键名。
    • 使用 JSON.parse() 替代 eval()

真实案例

  • Lodash(CVE-2018-3721) :旧版 _.defaultsDeep 存在污染漏洞。
  • jQuery(CVE-2019-11358)$.extend(true, {}, payload) 可被利用。
  • Mongoose:未验证查询参数导致污染。

检测工具

  • Scannerpp-finder
  • Chrome DevTools :检查 Object.prototype 是否有异常属性。

总结:原型链污染源于 JavaScript 的动态原型机制,通过严格控制对象操作、避免递归处理用户数据、冻结原型或使用无原型对象,可有效防御此漏洞。

相关推荐
蒲公英eric1 天前
从客户端到服务端:DVWA DOM 型 XSS 模块完整漏洞分析教程
前端·web安全·ai·xss·dvwa·ai安全
Blockchina2 天前
Codex安全盲区:我用4组本地测试复盘SQLi、XSS、越权与路径穿越
sql·安全·xss
黄俊懿3 天前
【架构师从入门到进阶】第五章:DNS&CDN&网关优化思路——第七节:网关-XSS攻击与预防
网关·网络安全·架构·系统架构·架构师·xss·架构设计
HackTwoHub3 天前
Butter_Cookie 黄油曲奇|浏览器渗透插件,云存储检测、XSS、SQL 注入一站式 Web 安全测试工具
前端·sql·安全·web安全·网络安全·自动化·xss
Rain的Java大神之路9 天前
短信接口被狂刷怎么处理
java·运维·后端·web安全·面试·架构·xss
云水一下13 天前
零基础玩转bWAPP靶场(六十五):SQLiteManager XSS
web安全·xss·bwapp·sqlitemanager·cve-2012-5105·bee-box
TJHHH.14 天前
XSS-labs-master
前端·web安全·xss
DsirNg14 天前
登录态失控时,前端如何止损:从令牌轮换到会话退出的完整设计
xss·csrf·cookie·会话管理·前端安全·登录态·刷新令牌
云水一下14 天前
零基础玩转bWAPP靶场(六十四):XSS - Reflected (Custom Header)
web安全·xss·bwapp·header·custom·reflected
障碍的枫子16 天前
xss和CSRF的攻击和防御
前端·xss·csrf