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
html() vs innerHTML jquery/javascript & XSS attacks
提问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-html
div is empty, and test-innerhtml
div contans the script. Can someone tell me why? Is because html() is more secure against scripts injection or something similar?
如您所见,test-html
div 为空,test-innerhtml
div 包含脚本。有人能告诉我为什么吗?是因为 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\>');
While this will not:
虽然这不会:
var d = document.getElementById('xss');
d.innerHTML = '<script\>alert("XSS");</script\>';
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 question和this 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 等。