文章目录
Cookie🍪
概念
- 由服务端产生,存储在客户端,每次交互通过 request header带到服务端
- cookie不是http协议的内容, 只是浏览器提供的一种保持状态的机制
- 每个domain的cookie保存的数据不超过4KB, 很多站点还限制个数20
- 我的项目中使用过cookie的场景是tornado的secret cookie, 即后端返回
set-cookie
时,需要用服务器保存的密钥
给用户信息加盐
生产唯一签名值,这个cookie则是相对安全的。 - 一次请求抓包看cookie的设置和传递
Cookie存在的安全问题🚨
CSRF 跨站请求伪造
- 出现的条件
- 1.登录受信任网站A,并在本地生成Cookie。
- 2.在不登出A的情况下,访问危险网站B
- 3.危险网站B借助浏览器的机制携带Cookie像A发送漏洞请求,比如
付款链接
- 原理
- 首先需要明确浏览器的同源策略也就是跨域,已经规避了大多数的可能CSRF攻击
- 有一些标签或者属性是没有限制同源访问的,比如 img,link ,script ,iframe(iframe的src)等所有带src 属性的标签,还有表单提交
- 实质是将利用受害者的cookie跨域或者非跨域
- 重要的一点是
危险网站B
只能利用浏览器机制使用
Cookie, 而不能获取Cookie
或者说不能读取Cookie
内容 >>这点很重要, 后面防御csrf可以利用Set-Cookie
来给前端传递csrf-token
前端可以在每次表单提交增加一个隐藏字段来防御
后面细说…
- 攻击
- 攻击图示
TODO - 攻击方式
- GET
- 有一家
银行A
的网址为http://www.bank.com
- 付款接口为
GET http://www.bank.com/pay?money=100
- 用户登录
银行A
后输入账号密码
生成cookie
,并在调用付款接口时,携带以作鉴权 - 用户
未登出银行A
,此时访问危险网站B
,危险网站B有以下代码段:
<img src=http://www.bank.com/pay?money=100>
- 以上代码会在页面渲染时进行请求
GET http://www.bank.com/pay?money=100
,因为src不受同源策略的限制,那么此时浏览器会携带Cookie
进行付款请求,用户,危!!! - 同理
借助 img、link 、script 、iframe 的src 标签
也可以做出类似攻击
- 有一家
- POST/有
body
的其他方式(PUT…)- 用户被引导到
危险网站B
,并在网站B上进行表单编辑并提交 - 或者iframe隐藏表单用户无感知的发生表单提交
- 用户被引导到
- GET
- 如何防御
-
对于表单提交
- 表单编辑提交应该确认域名是否是
本域
,比如我们只在www.bank.com
进行表单编辑 - 表单
submit
需要使用后端指定的 csrf-token
隐藏字段机制来保证表单提交的安全性- 对于
前后端不分离架构
,需要后端在渲染好的页面比如登录/注册
页面的表单处增加
<input type="hidden" name="csrf_token" value="{{csrf_token()}}">
- 对于
前后端分离架构
,可以利用Set-Cookie
设置csrf-token
到cookie,这样前端可以拿到这个csrf-token
并在表单提交时hidden
到表单中 - 注意:
csrf-token
不是token
, 或者他完全可以不叫csrf-token
,前后端分离项目可以和前端约定,比如叫csrf-key
都可以,重要的是原理的理解
- 对于
- 表单编辑提交应该确认域名是否是
-
通用解决
- 使用token替代cookie进行鉴权 (建议方案)
- 对涉及到非幂等的接口一律采用非
GET
的方式来进行,这样可以避免src
标签GET请求攻击 验证码双重鉴定
对非幂等
的接口如一般的POST
接口, 比如付款接口,每次调用都会造成数据变化那就加手机验证码验证,又比如get详情页这种不会造成数据变化,那么可以不加验证
-
- 攻击图示
XSS 跨站脚本工具
- 攻击方式
- 向网站 A 注入 JS代码,然后执行 JS 里的代码,篡改网站A的内容
Session🔗
概念
- 见名思意: session 即会话保持
- 由服务端产生,存储在服务端,给客户端返回 sessionid
- session是一种方案,是抽象的,不存在的
- 存储可以采用数据库或者内存(redis也属于内存的一种)
- session ID的传递可以依赖cookie,如果cookie被禁止,那可以在query参数或者请求头给出, 很灵活
session和cookie的区别
- session和cookie不是对立概念,甚至不是一个维度的概念,cookie是物理存在的,而session可以借助cookie实现 sessionid的传递
存在的问题🚨
- 首先session保存在服务端,如果是单机部署,那可能存在的问题只是存储压力,但是如果是分布式服务则要考虑session的共享问题,线上的解决方案则一般是放到redis中存储。
- 如果session依然是借用Cokkie传递,那依然存在Cookie的安全问题,可以考虑放到
header
或者body
中
Token🔑
概念
- 服务端签发,客户端保存,服务端没有存储压力
- 使用固定的算法解析规则
- 可以通过固定header
Authorization
来携带到服务端 - 解决了session共享的问题,可以在多个用户间共享登录状态
- 时间戳写入 token用于验证是否过期
- token没有跨域问题,避开同源策略
- 避免了CSRF攻击
- app端使用token,web端使用 session+cookie
- 通常的格式为
token实体+时间戳
签名算法如MD5
加密
JWT (json web token)🐌
概念
- 一种token解决方案
- 服务器保存密钥
- 三个部分组成:头部header.载荷payload.签证signature
- header
- header声明类型和加密算法
- base64UrlEncode({“alg”: “HS256”, “typ”: “JWT”})
- header声明类型和加密算法
- payload
- 载荷用于保存实体信息
- base64UrlEncode({})
- 载荷用于保存实体信息
- signature
- 签名用于验证token
HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)
- 签名用于验证token
- JWT不能存储敏感信息,因为载荷是base64编码
- header