这本身是无害的:
document.getElementById("demo").innerHTML = '<script src="/me.js"></script>';
HTML5指定不应执行用innerHTML插入的标记。
一
然而(而且既然你在问这个问题),可能还有一个很小的机会(无可否认)可以利用:
// 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
很可能会气馁。例子:
警告:如果您的项目是进行任何形式的安全审查,那么使用内网HTML很可能会导致代码被拒绝。例如,如果在浏览器扩展中使用InNelHTML并将扩展提交给Addio.MyILL.ORG,它将不会通过自动审查过程。
一
反应有一种有趣的方式(劝阻)阻止你使用它:
DaveRuleStimNeNelHTML是对浏览器DOM中使用内网HTML的反应替代。一般来说,从代码中设置HTML是有风险的,因为它很容易无意中将用户暴露于跨站点脚本(XSS)攻击。因此,您可以直接从react设置html,但是您必须键入危险的setinnerhtml并传递一个带有html键的对象,以提醒自己这是危险的。
二
最后,我认为值得一提的是,埃帕斯卡雷罗和桑丁都有一个合理的观点。我们知道
<script>
通过注入时不会加载和/或执行
内层HTML
但这并不意味着你是安全的:
<div id="demo"></div>
<script>
document.querySelector('#demo').innerHTML =
'<img src="x.gif" onerror="alert(42)">';
</script>
工具书类
-
https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML#Security_considerations
-
https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml