html() 与 innerHTML jquery/javascript 和 XSS 攻击

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8318581/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 03:01:53  来源:igfitidea点击:

html() vs innerHTML jquery/javascript & XSS attacks

javascriptjqueryhtmlinputxss

提问by BeNdErR

I'm testing xss attacks on my own code. The example beneath is a simple box where an user can type whatever he wants. After pressing "test!" button, JS will show the input string into two divs.This is an example I made to explain better my question:

我正在我自己的代码上测试 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>

if you try to copy it into a .html file and run it, it will work fine, but if you try to input <script>alert('xss')</script>, only one alert box will be thrown: the one inside `test-html' div (with html() function).

如果您尝试将其复制到 .html 文件中并运行它,它将正常工作,但是如果您尝试输入<script>alert('xss')</script>,则只会抛出一个警告框:`test-html' div 中的那个(带有 html() 函数) )。

I really can't understand why this is happening, and also, inspecting the code with firebug gives me this result (after injecting the script)

我真的不明白为什么会这样,而且,用萤火虫检查代码给了我这个结果(在注入脚本之后)

<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>

as you can see test-htmldiv is empty, and test-innerhtmldiv contans the script. Can someone tell me why? Is because html() is more secure against scripts injection or something similar?

如您所见,test-htmldiv 为空,test-innerhtmldiv 包含脚本。有人能告诉我为什么吗?是因为 html() 对脚本注入或类似的东西更安全吗?

Thanks in advance, best regards.

提前致谢,最好的问候。

采纳答案by MatthewJ

JQuery strips out the script tags, which is why you aren't seeing it append to the dom let alone executing.

JQuery 去掉了脚本标签,这就是为什么你看不到它附加到 dom 的原因,更不用说执行了。

To see an explanation of why jquery strips it out, you can see John Resig's reply here: https://forum.jquery.com/topic/jquery-dommanip-script-tag-will-be-removed

要查看 jquery 为何将其删除的解释,您可以在此处查看 John Resig 的回复:https: //forum.jquery.com/topic/jquery-dommanip-script-tag-will-be-removed

Hope this helps

希望这可以帮助

回答by Erwan Legrand

Contrary to what is being said on this page, jQuery.html()and the many jQuery functionswhich accept HTML strings as arguments are more prone to DOM-based XSS injection than innerHTML, as noticed by the OP.

与此页面上所说的相反,正如 OP 所注意到的那样jQuery.html(),许多接受 HTML 字符串作为参数的jQuery 函数比 更容易发生基于 DOM 的 XSS 注入innerHTML

jQuery.html()extracts the <script>tags, updates the DOM and evaluates the code embedded in the script tags.

jQuery.html()提取<script>标签,更新 DOM 并评估嵌入在脚本标签中的代码

As a result, XSS can happen without user interaction even after the DOM is loaded when using jQuery.html().

因此,即使在使用jQuery.html().

This is very easy to demonstrate.

这很容易证明。

This will call alert():

这将调用alert()

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

http://jsfiddle.net/2TpHC/

http://jsfiddle.net/2TpHC/

While this will not:

虽然这不会:

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

http://jsfiddle.net/Tjspu/

http://jsfiddle.net/Tjspu/

Unfortunately, there are manyother code paths (sinks) which lead to calling eval()in jQuery. The security conscious will probably avoid jQuery altogether, as far as possible.

不幸的是,还有许多其他代码路径(接收器)导致调用eval()jQuery。有安全意识的人可能会尽可能地完全避免使用 jQuery。

Note that I do not claim that using innerHTML is an effective defense against XSS. It is not. Passing unescaped data to innerHTML is not safe, as pointed out by @daghan. One should alwaysproperly escape data when generating HTML.

请注意,我并没有声称使用 innerHTML 是对 XSS 的有效防御。它不是。正如@daghan 所指出的,将未转义的数据传递给innerHTML 是不安全的。生成 HTML 时,应始终正确转义数据。

回答by LoveAndCoding

This is similar to both this questionand this one. .html()strips out the script tags before it inputs the HTML and executes them separately.

这类似于this questionthis one.html()在输入 HTML 之前去掉 script 标签并单独执行它们。

As for why the second one is not being executed, it is because dynamically added scripts like that will not be run after the page has been loaded.

至于为什么第二个没有被执行,是因为页面加载完成后,动态添加的脚本不会运行。

But, as @Ben points out, there are a lot of XSS openings when accepting things like that. That said, if the information is being displayed on their own page, they can run any arbitrary code they want on their own machine. The big issue will be if you store this, or send this to other users. Unless you do that, there is no protecting users from themselves in these sorts of regards. Maybe knowing what you're trying to protect against will help.

但是,正如@Ben 指出的那样,在接受这样的事情时会有很多 XSS 漏洞。也就是说,如果信息显示在他们自己的页面上,他们可以在自己的机器上运行任何他们想要的任意代码。最大的问题是你是否存储它,或者将它发送给其他用户。除非你这样做,否则就无法在这些方面保护用户免受自己的伤害。也许了解您要防范的内容会有所帮助。

回答by Ben

yes jquery html won't render script tags

是的 jquery html 不会呈现脚本标签

but it isn't more secure because you can use many other xss payloads such as <a href>style , expression etc..

但它并不更安全,因为您可以使用许多其他 xss 有效负载,例如<a href>style 、 expression 等。