javascript - HTML.innerHTML 与 Jquery.html() - Javascript 执行

标签 javascript jquery html xss

引用: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()不被处决?

更新:对于演示,打开控制台,然后执行:

  1. document.body.innerHTML = "<iframe><iframe //><script>alert(1)</script>"
  2. $("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/

相关文章:

jquery - Bootstrap 在导航下方显示搜索栏

jquery - 我可以对不同的门户网站使用 ajax GET 请求吗?

html - 忽略父宽度或填充

javascript - 谷歌地图动态添加标记

javascript - 获取文本区域内当前光标位置下的文本

javascript - 在表格单元格上创建工具提示?

javascript - 向文本序列添加计数器

javascript - TreeTable 中可调整大小的列?

JavaScript 切换 Material Design Lite 开关

javascript - HTML 选择器多个,选项 "all"禁用所有其他选项