Web开发的安全之旅 | 青训营笔记

130 阅读9分钟

这是我参与「第四届青训营 」笔记创作活动的的第10天

前言

本篇文章将从攻击和防御角度介绍Web常见的攻击和防御手段

1. 攻击篇

1.1 ross-Site Scripting(XSS)

概述

XSS 主要是利用了开发者盲目信任用户的提交内容

XSS的一些特点:

  1. 通常难以从UI上感知(暗地执行脚本)
  2. 窃取用户信息(cookie/token)
  3. 绘制 UI (例如弹窗),诱骗用户点击/填写表单

举例

submit函数没有对content进行过滤就保存,那么在render执行查询嵌入DOM的时候就可能产生XSS攻击 可以直接提交恶意脚本

XSS类别

1. Stored XSS 存储型XSS

  • 恶意脚本被存在数据库中
  • 访问页面 -> 读数据 === 被攻击
  • 危害最大,对全部用户可见

2. Reflected XSS 反射型

  • 不涉及数据库
  • 从 URL 上攻击

3. DOM-based XSS 基于DOM的XSS攻击

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

Reflected XSS 和 DOM-based 的区别

  • 区别在于完成注入脚本的地方:Reflected从服务端注入,DOM-based从客户端注入

4. Mutation-based XSS 基于浏览器渲染DOM的区别的XSS攻击

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

示例:没人比我更懂浏览器:有的浏览器会进行如下的解析

1.2 Cross-site request forgery(CSRF) 跨站伪造请求

概述

CSRF的特点:

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

示例:

用户点击邮件中的恶意链接,然后恶意页面发送请求银行转账的接口,银行服务器认为有Cookie的请求为合法请求,就进行转账,这是用户收到短信,钱被转走了呜呜。

类型

攻击者可以伪造成get或post请求进行攻击

1. CSRF---GET攻击

2. CSRF---POST攻击

1.3 Injection 注入攻击

注入攻击主要为SQL注入攻击

SQL Injection SQL注入攻击

示例:

  1. 读取请求字段
  2. 直接以字符串的形式拼接SQL语句

然后攻击者发起如下请求

在服务端拼接后,执行SQL语句

注入攻击不止于SQL

如:

  • CLI

  • OS command

  • Server-Side Request Forgery(SSRF),服务端伪造请求

    • 严格而言,SSRF不是注入,但是原理类似

示例1:视频转换例子 CLI

示例2:读取+修改

示例3:SSRF示例

1.4 Denial of Service(DOS) DOS攻击

概述

DOS攻击,通过某种方式(构造特定请求),导致服务器资源被显著消耗,来不及响应更多请求,导致请求挤压,进而雪崩效应。

先了解一下正则表达式的贪婪模式:

  • 使用 ? 进行匹配, 满足一个即可
  • 不使用 ?进行匹配,行的我都要

DOS攻击类型

1. 基于正则表达式的DOS ReDos

贪婪:n次不行?n-1次再试试?---回溯

2. Distributed Dos(DDos) 大量的请求

短时间内,来自大量僵尸设备的请求流量,服务器不能及时完成全部请求,导致请求堆积,进而引发雪崩效应,无法响应新请求。

攻击特点:

  • 直接访问IP
  • 注意API
  • 消耗大量带宽(耗尽)

示例:

攻击者大量发送TCP请求,在进行TCP三次握手时,最后一次ACK没有返回,导致连接不能被释放,达到最大连接数,不能接收新请求了

1.5 基于传输层的攻击

最常见的攻击方式:中间人攻击

由中间人来进行客户端和服务端的通信,可以窃取信息,伪造信息。

中间人可以是一个恶意的页面,或者路由器,或者网络业务提供商(ISP)。

为什么中间人这种攻击会存在?

  1. 因为信息是明文传输的
  2. 信息的篡改不可知,无法验证
  3. 对方身份无法验证

2. 防御篇

2.1 XSS 的防御

记住:

  1. 永远不信任用户的提交内容
  2. 不要将用户提交内容直接转换成 DOM

防御XSS攻击的现成工具

但是有一个需求必须动态生成DOM,那怎么办?

可以这样防范:

  1. 针对string -> DOM:要对字符串进行转义

  2. 上传svg,由于svg标签中可以插入script标签,那么就可能执行js代码:我们需要先对svg代码进行扫描。

  3. 不要让用户自定义跳转链接

  4. 不要让用户自定义样式

插播:Same-origin Policy 同源策略

何为同源:协议,域名,端口相同,那么下面三个地址都不同源。

注意:http请求同源是没有问题的,但跨域就不行了。那么如何让跨域请求是允许的呢?

CSP(Content Security Policy) 内容安全策略

  • 设置哪些源(域名)被认为是安全的
  • 来自安全源的脚本可以执行,否则直接报错
  • 对 eval + inline script 说不

示例:

服务器的响应头部:

  1. 第一种只允许同源请求
  2. 第二种在允许同源请求下,还允许不同源的特定域名进行请求

浏览器 meta

2.2 CSRF 的防御

1. 通过验证域名防御

CSRF攻击是通过伪造请求进行攻击,那么服务器可以通过请求头中的Orgin或Referer的域名进行校验,是我的域名就接受,不是就拒绝。

2. 通过token进行防御

  1. 注意token必须和具体用户进行绑定,否则攻击者随便一个token也可以
  2. 注意token要设置过期时间,防止攻击者获取token进行攻击

绕过源限制的攻击-iframe 攻击如何防范?

假如攻击者在按钮后放置一个iframe,用户点击按钮穿透到iframe,就可能发送请求。

那么我们在服务端对所与响应设置响应头X-Frame-Options为DENY/SAME0RIGIN :

  • DENY 当前页面不能作为iframe加载
  • SAMEORIGIN 必须是同源页面才可以

注意:不要将GET请求 作为 GET + POST

如果有内容就执行更新,有可能一石二鸟

避免用户信息被携带: SameSite Cookie

如果CSRF利用用户权限,用户权限在Cookie中,如果请求没有携带Cookie,那么就没有CSRF攻击了。

SameSite Cookie的具体含义:

通过对Cookie的domain属性与页面域名进行验证,如果是A的话认定为第一方Cookie会携带Cookie;不是A的第三方服务就不会携带Cookie,从而避免CSRF利用用户权限。

那么依赖Cookie的第三方服务怎么办?

  • 内嵌一个X站服务器,识别不了用户登录态,发不了弹幕。

我们可以在服务端设置SameSite=None,不对SameSite做限制,但同时需要表明这个Secure确保这个Cookie是安全的。

SameSite 和 CORS 的对比

SameSite示例

假设关闭samesite

  • a.com向服务器发送请求,服务器返回以cookie形式返回a.com
  • b.com向服务器发送请求,服务器返回以cookie形式还返回a.com

但是如果我开启samesite,那么b.com就获取不到信息了

防御CSRF的正确姿势

  • 我们应该做一个中间件,来生成各种防御CSRF攻击的策略,来进行全面的防御

2.3 Injection 的防御

找到项目中查询SQL的地方,使用 prepared statement 对SQL语句进行预编译,会把它当作一个字符串,不会进行识别。

针对其他注入攻击

2.4 DOS的防御

针对DOS攻击

  1. 在审查代码的时候去除为贪婪模式的代码
  2. 使用工具进行代码扫描和正则性能测试
  3. 拒绝使用用户提供的正则表达式

针对DDOS

2.5 传输层的防御

防御中间人:使用HTTPS

1. HTTPS的特性:

  1. 可靠性:对明文进行加密
  2. 完整性:进行MAC验证
  3. 不可抵赖性:具有数字签名

2. HTTPS的基本过程:

3. HTTPS如何确保信息完整性:

在发送加密信息的时候,还会携带加密信息的hash值,接收方进行验证加密信息的hash值和携带的hash值是否相等,如果不相等就不通过。

数字签名?

签名者会有一对私钥和密钥,通过私钥对指定内容进行数学计算,生成签名;公钥持有者使用公钥对签名进行解密,如果是就通过。

4. HTTPS如何实现不可抵赖性:数字签名

CA会完成相关签名工作,服务提供方会把元信息和公钥合并成一个信息,使用CA提供的私钥进行签名,生成证书,传递给浏览器,浏览器通过CA颁发的公钥进行核验,如果证书通过,则服务方身份可信。 浏览器如何获取公钥,浏览器中包含大量CA签发的证书,证书中含有公钥。

5. HSTS:如何将HTTP请求升级到HTTPS

首先浏览器会向服务器发送一次请求,服务器会返回一个Strict-Transport-Security: max-age=3600,在3600s时间范围内,之后浏览器发送的http请求都会升级为https请求

6. Subresource Integrity(SRI)

静态资源被劫持篡改怎么办

SRI:对请求的script标签添加integrity属性:会标明当前摘要值的算法以及具体的摘要值,当浏览器发起请求资源时,拿到资源并下载之后,会对真实的资源根据inergrity属性进行hash计算,然后和之后的哈希值(摘要值)进行对比,如果值不一样,说明资源被篡改。

3. 总结

推荐读物

\