CVE-2019-11358分析
字数 1481 2025-08-29 08:32:24

JavaScript原型链污染漏洞分析与防御(CVE-2019-11358)

一、JavaScript原型基础

1. JavaScript的类与实例

  • 在JavaScript中,构造函数相当于类,通过new关键词或Object.create()方法创建实例
  • 示例:
function Func() {
    this.demo = 1;
}
var func = new Func();

2. prototype与__proto__

  • prototype属性

    • 所有JavaScript函数都有一个prototype属性,指向该构造函数的原型
    • 例如Func.prototype指向Func的原型
  • __proto__属性

    • 所有JavaScript实例对象都有一个__proto__属性,指向其实例对象的原型
    • 例如func.__proto__指向func的原型
  • 关系总结:

    • 实例对象的__proto__指向构造函数的prototype
    • 原型链终点为nullObject.prototype.__proto__ === null

二、JavaScript原型链机制

1. 原型链结构

  • 示例原型链:
    • func -> Func.prototype -> Object.prototype -> null
    • array -> Array.prototype -> Object.prototype -> null
    • date -> Date.prototype -> Object.prototype -> null

2. 继承查找过程

  • 属性查找顺序:

    1. 对象自身属性
    2. 对象的__proto__(构造函数的prototype
    3. 递归查找__proto__.__proto__直到null
  • 继承示例:

function Father() {
    this.first_name = 'Tome';
    this.last_name = 'Alpha';
}
function Son() {
    this.first_name = 'Lisa';
}
Son.prototype = new Father();
let son = new Son();
console.log(`Name: ${son.first_name} ${son.last_name}`);
// 输出:Name: Lisa Alpha

三、原型链污染机制

1. 基本原理

  • 通过控制对象属性名(特别是__proto__)和赋值操作,修改原型链上的属性
  • 影响范围:所有来自同一类、父祖类的对象

2. 污染条件

  1. 对象/数组的键名或属性名可控
  2. 存在赋值操作

3. 常见场景

  • 对象合并(merge)操作
  • 对象克隆(clone)操作

4. 污染示例

function merge(target, source) {
    for(let key in source) {
        if(key in source && key in target) {
            merge(target[key], source[key]);
        } else {
            target[key] = source[key];
        }
    }
}

// 污染成功示例
let demo1 = {};
let demo2 = JSON.parse('{"name": "h3", "__proto__": {"age": 20}}');
merge(demo1, demo2);
console.log(demo1.name, demo1.age); // h3 20

let demo3 = {};
console.log(demo3.age); // 20(污染成功)

四、CVE-2019-11358漏洞分析

1. 漏洞信息

  • 影响版本:jQuery < 3.4.0
  • 漏洞类型:原型污染
  • 危害:可能导致拒绝服务或代码执行

2. 漏洞原理

  • jQuery的extend函数在深拷贝模式下未正确处理__proto__属性
  • 攻击者可注入恶意属性污染Object原型

3. 关键代码分析

jQuery.extend = jQuery.fn.extend = function() {
    var options, name, src, copy, copyIsArray, clone,
        target = arguments[0] || {},
        i = 1,
        length = arguments.length,
        deep = false;
    
    // 深拷贝模式判断
    if(typeof target === "boolean") {
        deep = target;
        target = arguments[i] || {};
        i++;
    }
    
    // 遍历参数
    for(; i < length; i++) {
        if((options = arguments[i]) != null) {
            // 遍历属性
            for(name in options) {
                src = target[name];
                copy = options[name]; // 外部可控
                
                // 深拷贝处理
                if(deep && copy && (jQuery.isPlainObject(copy) || 
                   (copyIsArray = Array.isArray(copy)))) {
                    // 递归处理对象或数组
                    target[name] = jQuery.extend(deep, clone, copy);
                } else if(copy !== undefined) {
                    // 直接赋值
                    target[name] = copy;
                }
            }
        }
    }
};

4. 漏洞利用

  • PoC:
$.extend(true, {}, JSON.parse('{"__proto__": {"exploit": "h3rmesk1t"}}'));
console.log(exploit); // 输出"h3rmesk1t"
  • 复现步骤:
var jquery = document.createElement('script');
jquery.src = 'https://code.jquery.com/jquery-3.3.1.min.js';
let exp = $.extend(true, {}, JSON.parse('{"__proto__": {"exploit": "h3rmesk1t"}}'));
console.log({}.exploit); // 输出"h3rmesk1t"

五、防御措施

1. 官方修复方案

  • jQuery 3.4.0+版本增加了对__proto__属性的检查
  • 修复方式:检测到__proto__属性时跳过合并

2. 开发建议

  1. 避免使用不安全的对象合并/克隆操作
  2. 对用户输入的JSON数据进行严格过滤
  3. 检查对象属性名是否包含敏感键(如__proto__constructor等)
  4. 使用Object.create(null)创建无原型的对象

3. 安全编码示例

// 安全的merge函数
function safeMerge(target, source) {
    for(let key in source) {
        if(key === '__proto__' || key === 'constructor' || key === 'prototype') {
            continue; // 跳过敏感键
        }
        if(key in source && key in target) {
            safeMerge(target[key], source[key]);
        } else {
            target[key] = source[key];
        }
    }
}

六、总结

JavaScript原型链污染是一种通过修改对象原型链来影响所有相关对象的安全漏洞。CVE-2019-11358展示了jQuery在对象深拷贝时未正确处理__proto__属性导致的严重安全问题。开发者应当:

  1. 及时更新依赖库到安全版本
  2. 避免直接使用不受信任的JSON数据
  3. 实现安全的对象操作函数
  4. 了解原型链机制,编写防御性代码

通过理解原型链机制和污染原理,开发者可以更好地预防此类安全问题,构建更安全的JavaScript应用。

JavaScript原型链污染漏洞分析与防御(CVE-2019-11358) 一、JavaScript原型基础 1. JavaScript的类与实例 在JavaScript中,构造函数相当于类,通过 new 关键词或 Object.create() 方法创建实例 示例: 2. prototype与__ proto__ prototype属性 : 所有JavaScript函数都有一个 prototype 属性,指向该构造函数的原型 例如 Func.prototype 指向 Func 的原型 __ proto__ 属性 : 所有JavaScript实例对象都有一个 __proto__ 属性,指向其实例对象的原型 例如 func.__proto__ 指向 func 的原型 关系总结: 实例对象的 __proto__ 指向构造函数的 prototype 原型链终点为 null ( Object.prototype.__proto__ === null ) 二、JavaScript原型链机制 1. 原型链结构 示例原型链: func -> Func.prototype -> Object.prototype -> null array -> Array.prototype -> Object.prototype -> null date -> Date.prototype -> Object.prototype -> null 2. 继承查找过程 属性查找顺序: 对象自身属性 对象的 __proto__ (构造函数的 prototype ) 递归查找 __proto__.__proto__ 直到 null 继承示例: 三、原型链污染机制 1. 基本原理 通过控制对象属性名(特别是 __proto__ )和赋值操作,修改原型链上的属性 影响范围:所有来自同一类、父祖类的对象 2. 污染条件 对象/数组的键名或属性名可控 存在赋值操作 3. 常见场景 对象合并(merge)操作 对象克隆(clone)操作 4. 污染示例 四、CVE-2019-11358漏洞分析 1. 漏洞信息 影响版本:jQuery < 3.4.0 漏洞类型:原型污染 危害:可能导致拒绝服务或代码执行 2. 漏洞原理 jQuery的 extend 函数在深拷贝模式下未正确处理 __proto__ 属性 攻击者可注入恶意属性污染Object原型 3. 关键代码分析 4. 漏洞利用 PoC: 复现步骤: 五、防御措施 1. 官方修复方案 jQuery 3.4.0+版本增加了对 __proto__ 属性的检查 修复方式:检测到 __proto__ 属性时跳过合并 2. 开发建议 避免使用不安全的对象合并/克隆操作 对用户输入的JSON数据进行严格过滤 检查对象属性名是否包含敏感键(如 __proto__ 、 constructor 等) 使用 Object.create(null) 创建无原型的对象 3. 安全编码示例 六、总结 JavaScript原型链污染是一种通过修改对象原型链来影响所有相关对象的安全漏洞。CVE-2019-11358展示了jQuery在对象深拷贝时未正确处理 __proto__ 属性导致的严重安全问题。开发者应当: 及时更新依赖库到安全版本 避免直接使用不受信任的JSON数据 实现安全的对象操作函数 了解原型链机制,编写防御性代码 通过理解原型链机制和污染原理,开发者可以更好地预防此类安全问题,构建更安全的JavaScript应用。