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 阶段避免innerHTML
、outerHTML
的 XSS 隐患。
参考: 如何防止XSS攻击?