Как я могу получить значение функции без toString ()? - PullRequest
5 голосов
/ 27 февраля 2020

Мне нужно убедиться, что некоторые указанные c собственные Javascript функции не исправлены и не переопределены.

К сожалению, я не могу сделать это с помощью доступа к .toString() функции или Function.prototype.toString с помощью одного из применений или вызовов bind, поскольку Function.prototype.toString - это одна из функций, которую я должен проверить.

Есть ли другой метод, который возвращает значение (саму функцию) функции? (Или [Native Code] для собственных JS функций)

Редактирование: Одна из целей этого теста - проверить, является ли клиент ботом, который исправляет некоторые JS функции. Создание нового фрейма и получение значения Function.prototype.toString в этом случае не сработает

1 Ответ

1 голос
/ 27 февраля 2020

В ответ на редактирование

Если это вредоносный клиент, который не может или не хочет обновлять свой скрипт бота в ответ на ваши проверки, просто сохраните копию Function.prototype.toString() используя javascript в заголовке HTML для переменной temp. Затем проверьте это, чтобы убедиться, что клиент вообще не мутировал js.

Если клиент злонамеренный И пытается активно избегать ваших проверок, меняя своего бота, то просто нет железных оболочек способ остановить их. Это станет гонкой вооружений, где вы исправляете чеки, а они исправляют в ответ. В конечном счете, клиент имеет решающее значение в том, что запускается в его браузере, поэтому вы можете еще раз подумать о том, почему вы делаете эти проверки, чтобы увидеть, есть ли другой жизнеспособный подход к вашей проблеме.

Начальный ответ

Вы можете повторно запросить весь файл. js и проанализировать его как строку. Вам придется сделать это для каждого файла js и найти хороший шаблон для определения того, были ли перезаписаны ваши функции, поэтому он может не работать для ваших нужд.

// my JS file is being served from giorgiosjames.com/myjs.js

const myJs = await fetch('giorgiosjames.com/myjs.js').then(res => res.text());

// parse myJs here, something like
if (myJs.includes('Function.prototype.toString = ')) // do something

Если вы можете ограничить свое использование самой последней Firefox, вы можете использовать метод .toSource(), но ни один другой браузер не поддерживает его, и он не является стандартным. Подробнее читайте здесь

// only in latest Firefox
const x = () => 'wow';
console.log(x.toSource())
// returns "() => 'wow'"

И в качестве каркасной задачи вы, вероятно, все еще можете использовать (возможно) лучший подход Function.prototype.toString с помощью:

  1. Первая проверка работоспособности toString.

  2. Сброс .toString(), если он был переопределен.

  3. Проверка других функций с помощью .toString()
  4. Демонтаж .toString() при необходимости
let temp = null;

if (Function.prototype.toString.toString() !== 'function toString() { [native code] }') {
    // save overridden function if you need to come back to it
    temp = Function.prototype.toString;

    // getting the original toString function by creating an iframe
    const iframe = docuemnt.createElement('iframe');
    iframe.style.display = 'none';
    document.body.appendChild(iframe);
    Function.prototype.toString = iframe.contentWindow.Function.prototype.toString;
}

// do your other checks here ex//
if (Array.prototype.includes.toString() !== iframe.contentWindow.Array.prototype.includes.toString()) {
    // do something
}

// ..or however you're planning on checking for overridden functions

// restore toString from temp if needed.
Function.prototype.toString = temp;
...