代码之家  ›  专栏  ›  技术社区  ›  timpone

这可能是javascript中的xss攻击吗

  •  -6
  • timpone  · 技术社区  · 6 年前

    我正在研究一些遗留应用程序,想知道这是否是一个可行的xss利用?

    代码:

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

    我不这么认为,但外面有比我更聪明的人。这有变化吗?

    1 回复  |  直到 6 年前
        1
  •  0
  •   customcommander    6 年前

    这本身是无害的:

    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>

    工具书类

    1. https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML#Security_considerations
    2. https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml