首页 > 解决方案 > Object.prototype.toString.call() 是一个安全问题吗?

问题描述

我的疑问是:我应该只检查原始值(即使用Number.isFinite()or Number.isInteger()),因为“对象”值容易出现安全漏洞吗?

如果是,s _.isNumber()应该避免使用像 Underscore'(基于 Object.toString)这样的方法吗?

这是一个恶意对象的示例,它的行为类似于数字,但可以执行任何代码。

class Num extends Number {

    constructor (q) {
        super (q);
        this.value = q;
    }

    valueOf () {
        console.log('HACKED');
        return this.value;
    }
}

var n = new Num(5); // Num {5, value: 5}
console.log(Object.prototype.toString.call(n)); // [object Number]
console.log(Number.isFinite(n)); // false
var x = n + 1; // HACKED
console.log(x); // 6

标签: javascriptsecurityunderscore.jsprimitive

解决方案


我不知道你的意思是,恶意对象的行为像一个数字,但可以执行任何代码

您所做的只是覆盖valueOf您自定义 Object 的方法Num

来自 MDN,

JavaScript 调用 valueOf 方法将对象转换为原始值

在您的代码var x = n + 1;中,由于 n 是 Object 类型,而 1 是原始类型,javascript 会尝试调用valueOf以获取 n 的原始值并将其添加到 1。

由于它是您自己的对象和您的覆盖valueOf方法,因此您的自定义valueOf将被执行以将 Object 转换为原始类型。

阅读有关valueOf的更多信息。


推荐阅读