html () vs innerHTML jquery / javascript и XSS-атаки - PullRequest
9 голосов
/ 30 ноября 2011

Я тестирую xss-атаки на свой собственный код. Пример ниже представляет собой простое поле, в котором пользователь может вводить все, что он хочет. После нажатия "проверить!" Кнопка JS покажет входную строку в два div.Это пример, который я сделал, чтобы лучше объяснить мой вопрос:

<html>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
    function testIt(){
        var input = document.getElementById('input-test').value;
        var testHtml = document.getElementById('test-html');
        var testInnerHTML = document.getElementById('test-innerHTML');
        $(testHtml).html(input);
        testInnerHTML.innerHTML = input;
    }
</script>
<head>this is a test</head>
<body>  
    <input id="input-test" type="text" name="foo" />
    <input type="button" onClick="testIt();" value="test!"/>
    <div id="test-html">
    </div>
    <div id="test-innerHTML">
    </div>
</body>

если вы попытаетесь скопировать его в файл .html и запустить его, он будет работать нормально, но если вы попытаетесь ввести <script>alert('xss')</script>, будет выдано только одно окно с предупреждением: одно внутри div `test-html ' (с функцией html ()).

Я действительно не могу понять, почему это происходит, а также проверка кода с помощью firebug дает мне этот результат (после внедрения скрипта)

<body>
this is a test
<input id="input-test" type="text" name="foo">
<input type="button" value="test!" onclick="testIt();">
<div id="test-html"> </div>
<div id="test-innerHTML">
  <script>
    alert('xss')
  </script>
</div>
</body>

как видите test-html div пуст, а test-innerhtml div содержит скрипт. Может кто-нибудь сказать мне, почему? Это потому, что html () более защищен от внедрения скриптов или чего-то подобного?

Заранее спасибо, с наилучшими пожеланиями.

Ответы [ 4 ]

20 голосов
/ 10 апреля 2013

Вопреки тому, что говорится на этой странице, jQuery.html() и многие функции jQuery , которые принимают строки HTML в качестве аргументов , более подвержены внедрению XSS на основе DOM, чем innerHTML, как заметил OP.

jQuery.html() извлекает теги <script>, обновляет DOM и оценивает код, встроенный в теги сценария .

В результате XSS может происходить без взаимодействия с пользователем даже после загрузки DOM при использовании jQuery.html().

Это очень легко продемонстрировать.

Это вызовет alert():

$('.xss').html('<script>alert("XSS");</script\>');

http://jsfiddle.net/2TpHC/

Пока этого не будет:

var d = document.getElementById('xss');
d.innerHTML = '<script\>alert("XSS");</script\>';

http://jsfiddle.net/Tjspu/

К сожалению, есть много другие пути кода (приемники), которые приводят к вызову eval() в jQuery.Специалисты по безопасности, вероятно, будут избегать jQuery, насколько это возможно.Это не.Передача неэкранированных данных в innerHTML небезопасна, на что указывает @daghan.Нужно всегда правильно экранировать данные при генерации HTML.

6 голосов
/ 30 ноября 2011

JQuery удаляет теги сценария, поэтому вы не видите, чтобы он добавлялся к dom, не говоря уже о выполнении.

Чтобы увидеть объяснение того, почему jquery удаляет его, вы можете увидеть ответ Джона Резига здесь: https://forum.jquery.com/topic/jquery-dommanip-script-tag-will-be-removed

Надеюсь, это поможет

1 голос
/ 30 ноября 2011

Это похоже на этот вопрос и этот ..html() удаляет теги сценария перед тем, как вводить HTML, и выполняет их отдельно.

Что касается того, почему второй не выполняется, то это потому, что динамически добавленные сценарии, подобные этому, не будут запускаться после страницыбыл загружен.

Но, как указывает @Ben, существует множество открытий XSS при принятии подобных вещей.Тем не менее, если информация отображается на их собственной странице, они могут запускать любой произвольный код на своем компьютере.Большая проблема будет, если вы сохраните это или отправите другим пользователям.Если вы этого не сделаете, в такого рода отношениях нет защиты пользователей от самих себя.Может быть, знание того, от чего вы пытаетесь защитить, поможет.

1 голос
/ 30 ноября 2011

да jquery html не будет отображать теги скрипта

но это не более безопасно потому что вы можете использовать множество других полезных нагрузок xss, таких как стиль <a href>, выражение и т. д.

...