我正在研究一些旧版应用程序,并且好奇这是否是可行的XSS漏洞?
代码:
<div id="demo"></div>
<script>
document.getElementById("demo").innerHTML = '<script src="/me.js"></script>';
</script>
我不这么认为,但是那里有比我聪明的人。这有变化吗?
答案 0 :(得分:0)
这本身是无害的:
document.getElementById("demo").innerHTML = '<script src="/me.js"></script>';
HTML5指定不应执行innerHTML插入的标记。 1
但是(并且既然您在询问),仍然有可能(仍然可以)极少地利用它:
// This is the backdoor that an attacker has to inject somehow
Object.defineProperty(Element.prototype, 'innerHTML', {
set: function (value) {
const script = document.createElement('script');
script.textContent = `alert('gotcha! ${value}')`;
document.body.appendChild(script);
}
});
// This is what you're doing in your app
document.getElementById("demo").innerHTML = '<script src="/me.js"><\/script>';
<div id="demo"></div>
如您所见,解析和提取URL并将脚本重新注入页面很容易。
如今,不建议使用innerHTML
。示例:
警告:如果您的项目是将接受任何形式的安全检查的项目,则使用innerHTML最有可能导致代码被拒绝。例如,如果您在浏览器扩展中使用innerHTML并将扩展提交给addons.mozilla.org,它将不会通过自动审核过程。 1
React有一种有趣的方式(IMHO)可以阻止您使用它:
dangerouslySetInnerHTML是React在浏览器DOM中使用innerHTML的替代品。通常,通过代码设置HTML是有风险的,因为很容易在无意间使用户遭受跨站点脚本(XSS)攻击。因此,您可以直接从React设置HTML,但是您必须输入angerousedSetInnerHTML并使用__html键传递对象,以提醒自己这很危险。 2
最后,我认为值得一提的是epascarello和E. Sundin都有道理。我们知道<script>
在通过innerHTML
注入时不会加载和/或执行,但这并不意味着您很安全:
<div id="demo"></div>
<script>
document.querySelector('#demo').innerHTML =
'<img src="x.gif" onerror="alert(42)">';
</script>
参考