缘起
- 在当今数字化的世界中,互联网已经成为我们生活的重要组成部分;而web作为获取资讯的窗口,其
安全问题
值得每一个程序员重视
什么是 XSS
- Cross-Site Scripting(跨站脚本攻击)简称
xss
,是一种代码注入攻击,攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行 - 利用这些恶意脚本,攻击者可以获取用户敏感信息如(Cookie、SessionID)等,进而危害数据安全
- xss 的本质:用户提交的数据未过滤,渲染到了 HTML 上,结果被浏览器当成了代码,浏览器无法分辨哪些代码是可信的,导致恶意代码被执行
恶意注入代码的方式
- 来自用户的 UGC(用户生成内容)信息
- URL 参数
- POST 参数 --- Referer
- Cookie
- UA
- 。。。
XSS 的危害
- 攻击者能够在用户的页面上运行恶意 js,将相当于取得了整个页面的浏览器上控制权,攻击者可以干的事情包括但不限于以下
- 获取用户敏感信息,监听表单输入,获取 cookie 等
- 冒充用户发起操作请求,在恶意脚本中利用用户的登录状态进行货币、物品等转账;更改权限管理
- 钓鱼;弹窗;更改页面外观;
- 挖矿 占用 cpu,消耗资源
- 发起 dos 攻击,所有被 XSS 的用户对某个目标发起资源请求
- XSS 蠕虫;如果是社交平台的 XSS,在恶意脚本中利用用户的登录状态进行关注、发状态、发私信等操作, 发出的状态和私信可再带上攻击 URL,诱导多人点击,不断放大攻击范围
- ...
XSS 的分类
根据攻击的来源,XSS 攻击可分为存储型
、反射型
和DOM型
三种
存储型 XSS
- 攻击者将恶意代码提交到目标网站的数据库中
- 用户打开目标网站,网站服务端将恶意代码从数据库中取出,拼接在 html 中返回给浏览器
- 用户浏览器收到响应,恶意代码也会被执行
示例
- 我们通过
nest/cli
创建demo示例
,如果对nest
不熟悉,狠戳这里
反射型 XSS
- 攻击者构造出特殊的 URL,其中包含恶意代码
- 用户打开有恶意代码的 url 时,往后咱服务端将恶意代码从 url 中取出,拼接在 html 中返回给浏览器
- 用户浏览器收到响应,恶意代码也会被执行
示例
- 我们通过
nest/cli
创建demo示例
,如果对nest
不熟悉,狠戳这里
注意:
- 反射型 XSS 和存储型 XSS 的区别在于,存储型 XSS 的恶意代码存在数据库中,反射型 XSS 的恶意代码存储在 URL 中
- 反射型 XSS 常通过 URL 传递参数注入攻击 -由于需要用户主动打开恶意的 URL 才能生效,攻击者往往会结合多种手段诱导用户点击
DOM 型 XSS
- 攻击者构造出特殊的 URL,包含恶意代码
- 用户打开带有恶意代码的 URL
- 用户浏览器接到响应后,前端代码将 URL 中的数据插入到 DOM 中,或者在 js 中进行了
eval
操作,恶意代码被执行
DOM 型 XSS 和前俩种的区别在于,DOM 型是 js 自身的安全漏洞、其他俩种属于服务端漏洞
示例
- 我们通过
nest/cli
创建demo示例
,如果对nest
不熟悉,狠戳这里
XSS 防御
一般情况
- 如果用模版引擎可以使用
转义html标签
,以ejs模版引擎为例
,使用<%= %>
代替<%- %>
,同时ejs
提供了大量标签用于不同情况的显示 - 更多资料请狠戳这里
- 如果使用现代框架
vue
、react
等,慎用v-html
以及dangerouslySetInnerHTML
,如果不得已的情况下,可以考虑通过转义字符
代替标签
- 慎用
eval
函数,他会把字符串
转换成js
代码供浏览器执行
富文本情况
-
说明
-
一些需要提交富文本的功能,比如营销内容、公告内容,需要用到html标签,可能要以html格式来保存。这种情况下上述转义的方法就不适用了。
-
这时就必须识别出XSS攻击代码了,识别出来有两种处理方法,一是拦截,直接 403 Forbidden;二是过滤,一般是删掉或者替换然后存入数据库。
-
不推荐过滤处理,容易被绕过
-
-
方案
- 禁用富文本中的
敏感标签
,script、 Object 标签 - 禁止
a
标签的href属性中出现javascript
关键字 - 禁止标签中出现
onerror
方法,尤其是在img
标签中;如果无特殊场景,禁用所有以on
开头的属性 - 使用xss npm库
- 禁用富文本中的