美文网首页
innerHTML 的漏洞与安防

innerHTML 的漏洞与安防

作者: wfatec | 来源:发表于2019-08-02 16:20 被阅读0次

    innerHTML的漏洞

    早期的前端开发人员在写代码时通常会用到 element.innerHTML() 方法,实际上这个方法是存在很大漏洞的,来看下面一个例子:

    var element = document.getElementById("root");
    element.innerHTML = '<script>alert("XSS Attack");</script>';
    

    看到这里似乎完成了一个简单的 XSS 攻击。执行一下,发现什么都没有发生 😂。事实上,内建的安全机制已经将传入的 DOM 进行了解析并执行。这里我查阅了一下文档,里面有这样一段话:

    HTML 5 中指定不执行由 innerHTML 插入的 <script> 标签。然而,有很多不依赖 <script> 标签去执行 JavaScript 的方式。所以当你使用 innerHTML 去设置你无法控制的字符串时,这仍然是一个安全问题。例如:

    var element = document.getElementById("root");
    element.innerHTML = "<img src=x onerror=\"alert('XSS Attack')\">";
    

    此时,我们注入的脚本还是被执行了。

    安防方案

    1. 使用 textContent
    element.textContent = "<img src=x onerror=\"alert('XSS Attack')\">";
    

    此时,我们会将 <img src=x onerror="alert(\'XSS Attack\')"> 以字符串的形式来存取,因而可以避免执行脚本.

    1. 对待传入 DOM 的内容进行净化

    虽然 textContent 能解决一部分问题,但是并不能解决所有问题,当我们需要添加额外的标记时,还是需要使用 innerHTML 的。例如:

    element.innerHTML = "<h1>" + yourString + "</h1>";
    

    这个时候,我们只能选择对 yourString 进行净化:

    var sanitizeHTML = function(str) {
      var temp = document.createElement("div");
      temp.textContent = str;
      return temp.innerHTML;
    };
    

    通过创建一个临时的 div 并通过 textContent 存入内容,从而将特殊字符进行转译,然后再通过 innerHTML 返回这些转译过的内容,这是因为 innerHTML 可以阻止转译后的字符被转换回未转译的状态。

    var div = document.getElementById("root");
    div.innerHTML =
      "<h1>" +
      sanitizeHTML("<img src=x onerror=\"alert('XSS Attack')\">") +
      "</h1>";
    

    这是一种更为通用的做法。

    参考

    Preventing cross-site scripting attacks when using innerHTML in vanilla JavaScript

    相关文章

      网友评论

          本文标题:innerHTML 的漏洞与安防

          本文链接:https://www.haomeiwen.com/subject/knnldctx.html