Можно ли вводить вредоносный код javascript через $()?

Пример:

if($('#' + untrusted_js_code).length) > 0
  ....`

Обычно "untrusted_js_code" должен быть простой строкой, представляющей идентификатор элемента. Значение переменной происходит из iframe (через postMessage), поэтому он не доверен. И я просто проверяю, существует ли этот элемент на текущей странице, и только потом делайте что-нибудь с ним.

Ответы

Ответ 1

По состоянию на 22/10/2012, jQuery 1.8.2:

Да, возможны атаки XSS.

var input = "<script>alert('hello');</script>"
$(input).appendTo("body");

См. демонстрацию. Кажется, команда jQuery подтвердила это и планирует обратиться к ней в jQuery 1.9.

Как и в jQuery 1.8, используйте $.parseHTML, если вы ожидаете, что пользовательский ввод будет html:

var input = "<script>alert('hello');</script>"
$($.parseHTML(input)).appendTo("body");​

См. демонстрацию, никаких предупреждений.


В случае, когда OP описывает, однако, следующее:

var untrusted_js_code = 'alert("moo")';
$('#' + untrusted_js_code).show();

Переведем на это:

$('#alert("moo")').show();

Это intrepreted jQuery как селектор CSS, благодаря предыдущему # в строке, который, как и html, не может иметь встроенный JS-код, поэтому он относительно безопасен. В приведенном выше коде только jQuery будет искать элемент DOM этим идентификатором, в результате чего jQuery не сможет найти элемент и, следовательно, не будет выполнять никаких действий.

Ответ 2

Да, если вы используете более старую версию jQuery, это возможно в некоторых случаях. Это было исправлено (здесь commit) в версии 1.6.3. Также см. соответствующий отчет об ошибках.

Конец включает тестовый пример, который разъясняет проблему:

jQuery( '#<img id="check9521" src="no-such-.gif"' +
        'onerror="jQuery._check9521(false)">' ).appendTo("#qunit-fixture");

С версиями jQuery до 1.6.3 код onerror был бы выведен.

В вашем конкретном примере (только для проверки длины) эта проблема не возникает.

Ответ 3

С этим утверждением вы запрашиваете jQuery для выполнения запроса на основе селектора. Являясь строкой селектора, она не может навредить.

Ответ 4

Это не так ясно, как говорят другие. Неверный код не сможет выполнять XSS (если у вас есть достаточно новая версия jQuery, как указывает Балфа), но она может зависать с пользовательским браузером или сделать ваш код неожиданным.

Например, если untrusted_js_code был :input, перевод был бы следующим:

$("#:input")

и jQuery, похоже, просто игнорирует # и соответствует :input. Серьезно, откройте консоль и запустите этот бит кода на этой странице. (Кажется, это работает только с псевдоклассами.)

Недобросовестная сторона может дать вам вычислительно-интенсивный селектор (очень упрощенно :not(.asdf):not(.asdf) десятки тысяч раз), который обрабатывает секунды (или минуты...).

(Кроме того, есть вероятность ошибок браузера, поэтому селектор может быть создан для сбоя веб-браузера пользователей.)