Object.prototype.toString.call () является проблемой безопасности? - PullRequest
0 голосов
/ 27 апреля 2018

Я сомневаюсь: стоит ли проверять только примитивные значения (т. Е. С использованием Number.isFinite() или Number.isInteger()), поскольку значения «объекта» подвержены ошибкам безопасности?

Если да, таких методов, как Underscore 's _.isNumber() (основанных на Object.toString), следует избегать?

Вот пример вредоносного объекта, который действует как Number, но может выполнять любой код.

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

1 Ответ

0 голосов
/ 27 апреля 2018

Я не уверен, что вы подразумеваете под вредоносным объектом, который действует как число, но может выполнять любой код

То, что вы сделали, это просто переопределили метод valueOf вашего пользовательского объекта Num.

от MDN,

JavaScript вызывает метод valueOf для преобразования объекта в примитивное значение

В вашем коде var x = n + 1;, поскольку n имеет тип Object, а 1 имеет примитивный тип, javascript пытается вызвать valueOf, чтобы получить примитивное значение n и добавить его к 1.

Поскольку это ваш собственный объект с вашим методом overidden valueOf, ваш пользовательский valueOf будет выполнен для преобразования объекта в примитивный тип.

Подробнее о valueOf .

...