2016-11-14 3 views
3

Ref: html() vs innerHTML jquery/javascript & XSS attacksHTML.innerHTML против Jquery.html() - выполнение Javascript

Из этого я могу сделать вывод, что Jquery извлекает <script> теги и выполнить отдельно в DOM, он не появляется в DOM.

Рассмотрим следующий HTML-код:

а = <iframe><iframe //><script>alert(1)</script>

б = <iframe><iframe> //<script>alert(1)</script>

Как кода в a, body.innerHTML = a; не выполняет сценарий, но $("body").html(a); делает.

Почему? JQuery .html() выполняет контент после //, но .innerHTML = нет?

Если это так, почему b внутри .innerHTML = или .html() не выполняется?

Обновление: Для демонстрации, откройте консоль и выполните следующее:

  1. document.body.innerHTML = "<iframe><iframe //><script>alert(1)</script>"
  2. $("body").html("<iframe><iframe //><script>alert(1)</script>");

1 не будет выполнять оповещение(), но 2 будет. Замените значения HTML на b. Ни один из них не будет выполнен.

Update 2: Из того, что я могу определить, что HTML-код будет выполнен в Jquery-х body(), но не в .innerHTML=?

+4

'//' не является комментарием html ... они выглядят как '' – charlietfl

+0

И закрывающий тег тоже ошибочен – Bharat

+1

@BharatPatidar Я знаю, что это неправильно. Но для этого искаженного HTML-кода, почему это различие между .innerHTML() и JQuery .html()? –

ответ

2

Если вы посмотрите немного глубже в исходный код jQuery, мы найдем способ html.

В этом методе существует следующая line

this.empty().append(value); 

Если теперь перейти к append, мы можем найти следующий

append: function() { 
    return domManip(this, arguments, function(elem) { 
     if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { 
      var target = manipulationTarget(this, elem); 
      target.appendChild(elem); 
     } 
    }); 
} 

Итак, теперь найти domManip. Внутри эту функцию из HTML-строки устроится Фрагмен, и если фрагмент имеет тег сценария выполнение next code

DOMEval(node.textContent.replace(rcleanScript, ""), doc); 

Где DOMEval

function DOMEval(code, doc) { 
    doc = doc || document; 

    var script = doc.createElement("script"); 

    script.text = code; 
    doc.head.appendChild(script).parentNode.removeChild(script); 
} 

Так, по крайней мере, мы находим место, где выполнение сценариев.


Итак, почему в каком-то случае html запускать скрипт, а иначе нет?

Это зависит от строки ввода и того, что возвращается buildFragment function.

Внутри buildFragment мы нашли next line

tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter(elem) + wrap[ 2 ]; 

где elem является входной строкой и jQuery.htmlPrefilter является следующей функцией

htmlPrefilter: function(html) { 
    return html.replace(rxhtmlTag, "<$1></$2>"); 
} 

так, входная строка просто Заменена с некоторыми regular exporession rxhtmlTag.

rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, 

Так, просто попробуйте это для проверки строки:

console.log(jQuery.htmlPrefilter("<iframe><iframe //><script>alert(1)</" + "script>")); 
 
console.log(jQuery.htmlPrefilter("<iframe><iframe> // <script>alert(1)</" + "script>"));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>

Таким образом, в первом случае, как результат был

<iframe><iframe /></iframe><script>alert(1)</script> 

И после вставки его как innerHTML в tmp div, внутри div create два элементов: iframe и скрипт. Таким образом, после этого сценария, доступных для поиска и выполнения

Во втором случае:

<iframe><iframe> // <script>alert(1)</script> 

Строка не изменилась, а после вставки ее как innerHTML в tmp DIV внутри DIV создать только один элемент IFrame с кодированным контентом. Вот почему в этом случае скрипт не выполняется.

+0

Хотя это интересно, это также четко указано в документации: _By design, любой конструктор jQuery или метод, который принимает строку HTML - jQuery(), .append(), .after() и т. Д. - может потенциально выполнять код. Это может произойти путем вставки тегов скрипта или использования атрибутов HTML, которые выполняют код (например, ) _ – Mackan

+0

, и он отвечает, почему он выполняет a, но все еще не отвечает на реальный вопрос OP, почему '$ (" body ") .html ("