首页 > 解决方案 > 为什么这段代码不会污染 JavaScript 中的原型?

问题描述

我正在观看一些关于 JavaScript 中原型污染的视频,似乎我的代码应该受到影响,但测试代码不起作用:

// jQuery mock
var $ = {
    isArray: (x) => x instanceof Array
};


var Clone = {
    clone_object: function(object) {
        var tmp = {};
        if (typeof object === 'object') {
            if ($.isArray(object)) {
                return this.clone_array(object);
            } else if (object === null) {
                return object;
            } else {
                for (var key in object) {
                    if ($.isArray(object[key])) {
                        tmp[key] = this.clone_array(object[key]);
                    } else if (typeof object[key] === 'object') {
                        tmp[key] = this.clone_object(object[key]);
                    } else {
                        tmp[key] = object[key];
                    }
                }
            }
        }
        return tmp;
    },
    clone_array: function(array) {
        if (!is_function(Array.prototype.map)) {
            throw new Error("Your browser don't support ES5 array map " +
                            'use es5-shim');
        }
        return array.slice(0).map(function(item) {
            if (typeof item === 'object') {
                return this.clone_object(item);
            } else {
                return item;
            }
        }.bind(this));
    }
};

var clone = function(object) {
    return Clone.clone_object(object);
};

var x = JSON.parse('{"__proto__": {"foo": 10}}');
console.log(x);
var y = clone(x);
console.log(y);
var z = {};
console.log(z.foo);

是原型污染不再起作用还是我的代码有问题?如果问题出在代码上,调用克隆函数时需要更改什么污染?

标签: javascriptsecurity

解决方案


我想我知道问题是什么:

这是脆弱的:

({}).__proto__.x = 10
console.log(({}).x);

但这不是

var tmp = {}
var tmp2 = {x: 10};
tmp.__proto__ = tmp2;

因为第一个示例改变了现有__proto__对象,但第二个示例替换了整个__proto__属性,但不改变前一个__proto__对象。

问题中的代码创建了一个新的原型对象。它不会修改已创建对象的原型。


推荐阅读