22/10/12 xss攻击

81 阅读1分钟

XSS: Cross-Site Scripting(跨站脚本攻击)

先上一个最简单的xss攻击的例子 xss.html

<html>
  <body>
    <div id="title"></div>
  </body>
</html>
<script>
 // 简单的功能,就是想在页面上展示url上的title参数
 document.getElementById('title').innerHTML = decodeURIComponent(getTitle('title'))

 // 简单的解析
 function getTitle(variable){
    var query = window.location.search.substring(1);
    var vars = query.split("title=");
    return vars[1];
 }
</script>

但是当有人将链接设置为 xss.html?title=<script>alert("xss")</script> 时,按我的理解应该会有一个人弹出框,因为这就是一个xss攻击。

但是并没有,MDN上对于innerHTML的安全问题解释:

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

所以我们将链接换成 xss.html?title=<img src='x' onerror='alert("xss")'> 就成功了。
我们还可以利用 xss.html?title=<img src='x' onerror='alert(document.cookie)'> 就获取到了用户的cookie信息。

xss 攻击的分类

  • 存储型 XSS
    通过用户输入将恶意代码存储到数据库中,服务端取得恶意代码拼接到html返回到浏览器,比如在各种论坛评论中。
  • 反射型 XSS
    通过诱导用户点击恶意链接,在url中拼接恶意代码,服务端获取url后取得恶意代码拼接到html返回到浏览器,在用户打开页面时执行
  • DOM型 XSS 通过诱导用户点击恶意链接,在url中拼接恶意代码,前端直接获取url中的恶意代码并执行

存储型和反射型 XSS 都是需要后端进行处理,需要对数据进行对应的转义。但是前端也需要注意处理DOM型 XSS 攻击,虽然很难通过技术手段完全避免 XSS,但我们可以尽量减少漏洞的产生。

如果用 Vue/React 技术栈,并且不使用 v-html/dangerouslySetInnerHTML 功能,就在前端 render 阶段避免 innerHTMLouterHTML 的 XSS 隐患。

参考: 如何防止XSS攻击?