这是我参与「第四届青训营 」笔记创作活动的第1天
攻击方式
攻击方式主要有
- XSS(Cross-Site-Scripting)跨站脚本攻击
- CSRF攻击 (Cross-site request forgery)跨站域请求伪造
- injection 注入攻击
- Denial of Service(DOS)攻击
- 中间人攻击 (传输层) 本次主要介绍前两钟。
1. XSS(Cross-Site-Scripting)跨站脚本攻击
注入恶意脚本,完成攻击,造成泄露用户隐私等问题,主要利用了开发者对用户提交内容的盲目信任。
特点:
- 通常难以从 UI 上感知(一般都是暗地里执行脚本)
- 窃取用户信息(cookie/token)
- 绘制 UI(如弹窗等),诱骗用户点击 / 填写表单
xss 攻击也分几大类:Store XSS、Reflected XSS、DOM-based XSS、Mutation-based XSS
1.1 Store XSS
- 恶意脚背被存放在数据库中
- 访问页面->读数据 == 被攻击
- 危害最大,对全部用户可见
1.2 Reflected XSS
- 不涉及数据库
- 从URL上攻击
例如:
1.3 DOM-based XSS
- 不需要服务器参与
- 恶意攻击的发起和执行全在浏览器中完成
例如:
1.3 Mutation-based XSS
- 利用了浏览器渲染DOM的特性(独特优化)
- 不同浏览器会有区别
例如:
2. CSRF攻击 (Cross-site request forgery)跨站域请求伪造
特点:
- 在用户不知情的前提下
- 利用用户权限(cookie)
- 构造指定HTTP请求,窃取或修改用户敏感信息
例如:利用cookie调取银行页面接口请求
防御
1. 防御XSS
原则:永远不要新人用户提交的内容:不要将用户提交内容直接转换成DOM
- XSS现成防御工具:
- 前端:
- 主流框架(React、Vue)默认防御XSS
- google-closure-library
- 服务端(Node)
- DOMPurify
- 前端:
- 如果必须动态生成DOM
-
string -> DOM
使用
new DOMParser()类似 API 前必须将字符串进行转译。 -
上传 svg
提前扫描
svg标签,防止中间插入script脚本恶意代码。 -
自定义跳转链接
尽量不要让用户自定义跳转行为,如果做也一定要提前过滤。
-
自定义样式
攻击者通过伪造一个 CSS 代码在指定情况下发送一个请求,从而导致攻击,要避免。
-
2. CSP Content Security Policy 内容安全策略
该策略就是规定哪些域名是安全的,安全来源的脚本可以执行,否则报错。
主流配置是在服务器的额响应头配置
Content-Security-Police: script-src 'seft' //只允许同源
Content-Security-Police: script-src 'seft' http://domain.com //增加了允许的域名
前端可以在HTML中写浏览器meta信息
<meta> http-equiv = "Content-Srcurity-Police" content = "script-src self"</meta>
3. 防御CSRF
3.1 利用Cookie的SameSite属性
CSRF攻击中重要的一环就是自动发送目标站点下的 Cookie,然后就是这一份 Cookie 模拟了用户的身份。因此在Cookie上面下文章是防范的不二之选。
恰好,在 Cookie 当中有一个关键的字段,可以对请求中 Cookie 的携带作一些限制,这个字段就是SameSite。
SameSite可以设置为三个值,Strict、Lax和None。
a. 在Strict模式下,浏览器完全禁止第三方请求携带Cookie。比如请求sanyuan.com网站只能在sanyuan.com域名当中请求才能携带 Cookie,在其他网站请求都不能。
b. 在Lax模式,就宽松一点了,但是只能在 get 方法提交表单况或者a 标签发送 get 请求的情况下可以携带 Cookie,其他情况均不能。
c. 在None模式下,也就是默认模式,请求会自动携带上 Cookie。
3.2 验证来源站点
这就需要要用到请求头中的两个字段: Origin和Referer。
其中,Origin只包含域名信息,而Referer包含了具体的 URL 路径。
当然,这两者都是可以伪造的,通过 Ajax 中自定义请求头即可,安全性略差。
3.3 CSRF Token
Django作为 Python 的一门后端框架,如果是用它开发过的同学就知道,在它的模板(template)中, 开发表单时,经常会附上这样一行代码:
{% csrf_token %}
这就是CSRF Token的典型应用。那它的原理是怎样的呢?
首先,浏览器向服务器发送请求时,服务器生成一个字符串,将其植入到返回的页面中。
然后浏览器如果要发送请求,就必须带上这个字符串,然后服务器来验证是否合法,如果不合法则不予响应。这个字符串也就是CSRF Token,通常第三方站点无法拿到这个 token, 因此也就是被服务器给拒绝。