引用:html() vs innerHTML jquery/javascript & XSS attacks
据此,我可以推断,Jquery 提取了 <script>
标记并在 DOM 中单独执行,它不会出现在 DOM 中。
考虑以下 HTML 代码:
a = <iframe><iframe //><script>alert(1)</script>
b = <iframe><iframe> //<script>alert(1)</script>
截至 a
中的代码, body.innerHTML = a;
不执行脚本,但 $("body").html(a);
做。
为什么? Jquery 的 .html()
执行//
之后的内容但是.innerHTML =
不是吗?
如果是这样,为什么b
在.innerHTML =
里面或 .html()
不被处决?
更新:对于演示,打开控制台,然后执行:
-
document.body.innerHTML = "<iframe><iframe //><script>alert(1)</script>"
-
$("body").html("<iframe><iframe //><script>alert(1)</script>");
1 不会执行 alert(),但 2 会。将 HTML 值替换为 b
.两者都不会被执行。
更新 2: 据我所知,HTML 代码将在 Jquery 的 body()
中执行。但不在.innerHTML=
?
最佳答案
如果更深入地研究 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-string 构建的 fragmen 函数中,如果 fragment 有脚本标签执行 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 和 script。所以在这个脚本可用于查找和执行之后
第二种情况:
<iframe><iframe> // <script>alert(1)</script>
字符串未更改,将其作为 innerHTML 插入 tmp
div 后,在 div 内部仅创建一个带有编码内容的 iframe 元素。这就是为什么在这种情况下脚本不执行的原因。
关于javascript - HTML.innerHTML 与 Jquery.html() - Javascript 执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40583887/