2016-11-14 40 views
3

编号:html() vs innerHTML jquery/javascript & XSS attacksHTML.innerHTML VS Jquery.html() - JavaScript执行等

由此,我可以推断,Jquery的提取<script>标签和DOM分别执行,它不会出现在DOM。

考虑下面的HTML代码:

一个= <iframe><iframe //><script>alert(1)</script>

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

作为代码的在abody.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意志。用b替换HTML值。两者都不会被执行。

更新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的字符串这个函数建造fragmen,如果片段有脚本标记执行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创建两个元素:iframe和脚本。所以这个剧本,以备查找和执行

在第二种情况后:

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

字符串没有改变,在tmp DIV插入它的innerHTML后,里面的div创建编码的内容只是一个iframe元素。这就是为什么在这种情况下脚本不能执行。

+0

虽然很有趣,但在文档中也清楚地说明了这一点:通过设计,接受HTML字符串(jQuery(),.append(),.after()等)的任何jQuery构造函数或方法都可能执行代码。这可以通过注入脚本标签或使用执行代码的HTML属性(例如,)_ – Mackan

+0

它回答为什么它执行a,但仍然没有回答OP的真正问题,为什么'$(“body” ).html(“