这可能是Javascript中的XSS漏洞

问题描述 投票:-6回答:1

我正在研究一些遗留应用程序并且好奇这是否是一个可行的XSS漏洞?

码:

<div id="demo"></div>

<script>

document.getElementById("demo").innerHTML = '<script src="/me.js"></script>';
</script>

我不这么认为,但那里有比我聪明的人。这有变化吗?

javascript xss
1个回答
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有一种有趣的方式(恕我直言)阻止你使用它:

dangerouslySetInnerHTML是React在浏览器DOM中使用innerHTML的替代品。通常,从代码设置HTML是有风险的,因为很容易无意中将您的用户暴露给跨站点脚本(XSS)攻击。因此,您可以直接从React设置HTML,但是您必须键入dangerouslySetInnerHTML并使用__html键传递对象,以提醒自己这很危险。 2


最后,我认为值得一提的是epascarello和E. Sundin都有一个有效的观点。我们知道<script>在通过innerHTML注入时不会加载和/或执行,但这并不意味着你是安全的:

<div id="demo"></div>

<script>
document.querySelector('#demo').innerHTML =
  '<img src="x.gif" onerror="alert(42)">';
</script>

参考

  1. https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML#Security_considerations
  2. https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
© www.soinside.com 2019 - 2024. All rights reserved.