你真的理解 XSS 攻击嘛
在 web 安全中,我们常常会听到 XSS 攻击,这也是面试的时候会问的,但是你真的理解了吗?
XSS 攻击
XSS(Cross-Site Scripting,跨站脚本攻击)是一种常见的网络安全攻击手段。它主要利用了网页应用程序对用户输入数据的不充分处理,使得攻击者能够将恶意脚本注入到目标网页中。当其他用户访问这些被注入恶意脚本的网页时,脚本会在用户的浏览器中执行,从而实现攻击者的目的。
这样理解起来太抽象了,XSS 攻击其实是基于 document.innerHTML 这个 API 导致的。
如果我们使用 vue 的话,我们应该会用到 v-html 这个API,这时候我们可以看到在官方文档上写了一段描述,有没有想过是如何造成 XSS 攻击的呢?
document.innerHTML
Element.innerHTML 属性设置或获取 HTML 语法表示的元素的后代
这个 API 就是罪魁祸首
,它会解析你设置的内容
举个例子
javascript
const xssdom = document.getElementById("xss");
xssdom.innerHTML = "<script>alert('xss')</script>";
这时候你会发现页面没有反应,因为HTML 5 中指定不执行由 innerHTML 插入的script
标签。
详细见 developer.mozilla.org/zh-CN/docs/...
但是,我们可以不依赖 <script/>
去执行 JavaScript 方式,我们可以用 innerHTML 去设置你没有办法控制的字符串,例如
javascript
const name = "<img src='x' onerror='alert(1)'>";
xssdom.innerHTML = name;
这时候你会发现,你的页面中招了
这里的脚本执行,可以窃取到我们的用户信息,做任何想做的事情
恶意脚本
这时候你就会想,我又不是傻子,我怎么会写这个代码在页面上,我设置的 innerHTML 内容,我能不知道他的好坏嘛?诚然,但是如果这个数据是后端返回的呢?(那就是后端的问题,hhh)
攻击者会在评论中填写一些恶意脚本,被后端保存到服务器,然后当我们在处理一些评论展示的时候,评论中可能会包含表情,特殊字符,这些我们在解析的时候会通过 img 去展示,然后偷懒使用 innerHTML 一把梭去展示,就会产生这个问题,如图
解决方法
前端处理:
前端在输入和输出的任意一个时候进行转义
以上面的例子,返回的内容为
javascript
"<img src='x' onerror='alert(1)'>"
转义之后
具体的转义规则如下
当然,自己写确实很麻烦,我们可以直接使用 lodash 库中的方法 escape 即可 lodash.com/docs/4.17.1...
转义之后这段代码就不会作为脚本执行了,而是直接被渲染出来
总结
类型
这里只是大概说明了 xss 攻击的原理,根据恶意代码存储的位置不同,还有一些分类,如反射型 XSS
,存储型 XSS
,DOM 型 XSS
解决方案
这里也只说明了一种解决方案,其实还有一些,比如
- 使用 HTTPOnly Cookie 属性,防止 JavaScript 访问 Cookie
- 实施内容安全策略(CSP),限制可以执行的脚本类型和来源