Web开发安全 | 青训营笔记

117 阅读4分钟

这是我参与「第四届青训营 」笔记创作活动的第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上攻击

例如:

Demo

1.3 DOM-based XSS

  • 不需要服务器参与
  • 恶意攻击的发起和执行全在浏览器中完成

例如:

image.png

1.3 Mutation-based XSS

  • 利用了浏览器渲染DOM的特性(独特优化)
  • 不同浏览器会有区别

例如:

image.png

2. CSRF攻击 (Cross-site request forgery)跨站域请求伪造

特点:

  • 在用户不知情的前提下
  • 利用用户权限(cookie)
  • 构造指定HTTP请求,窃取或修改用户敏感信息

例如:利用cookie调取银行页面接口请求

image.png

防御

1. 防御XSS

原则:永远不要新人用户提交的内容:不要将用户提交内容直接转换成DOM
  • XSS现成防御工具:
    • 前端:
      1. 主流框架(React、Vue)默认防御XSS
      2. google-closure-library
    • 服务端(Node)
      1. DOMPurify
  • 如果必须动态生成DOM
    1. string -> DOM

      使用 new DOMParser() 类似 API 前必须将字符串进行转译。

    2. 上传 svg

      提前扫描 svg 标签,防止中间插入 script 脚本恶意代码。

    3. 自定义跳转链接

      尽量不要让用户自定义跳转行为,如果做也一定要提前过滤。

    4. 自定义样式

      攻击者通过伪造一个 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可以设置为三个值,StrictLaxNone

a.Strict模式下,浏览器完全禁止第三方请求携带Cookie。比如请求sanyuan.com网站只能在sanyuan.com域名当中请求才能携带 Cookie,在其他网站请求都不能。

b.Lax模式,就宽松一点了,但是只能在 get 方法提交表单况或者a 标签发送 get 请求的情况下可以携带 Cookie,其他情况均不能。

c.None模式下,也就是默认模式,请求会自动携带上 Cookie。

3.2 验证来源站点

这就需要要用到请求头中的两个字段: OriginReferer

其中,Origin只包含域名信息,而Referer包含了具体的 URL 路径。

当然,这两者都是可以伪造的,通过 Ajax 中自定义请求头即可,安全性略差。

3.3 CSRF Token

Django作为 Python 的一门后端框架,如果是用它开发过的同学就知道,在它的模板(template)中, 开发表单时,经常会附上这样一行代码:

{% csrf_token %}

这就是CSRF Token的典型应用。那它的原理是怎样的呢?

首先,浏览器向服务器发送请求时,服务器生成一个字符串,将其植入到返回的页面中。

然后浏览器如果要发送请求,就必须带上这个字符串,然后服务器来验证是否合法,如果不合法则不予响应。这个字符串也就是CSRF Token,通常第三方站点无法拿到这个 token, 因此也就是被服务器给拒绝。

参考

Web开发的安全之旅 -刘宇晨

浏览器灵魂之问,请问你能接得住几个?