来聊一聊Cookie(小甜饼),及其涉及到的web安全吧

最近在用thinkjs写自己的博客,发现总是掉到cookie的坑,于是就好好八一八这个小甜饼,没想到居然还说很有意思的,每一个知识点都能拉出一条大鱼,想想自己之前对cookie,简直就是它认识我,我只能叫出他的名字。

我将基于我自己的理解,使用原生koa2 + mysql来简单演示一下一些cookie的处理方案,有什么出岔子的地方,希望大家友好指正

1、cookie介绍

1.1 项目中cookie的使用场景

在实际的应用场景中,Cookie被用来做得最多的一件事是保持身份认证的服务端状态。比如登录状态的判断

1.2 为什么需要cookie呢?

敲黑板,HTTP是无状态协议,他不对之前发生过的请求和响应的状态进行管理。也就是每次服务器接收到请求后,并不知道请求到底用户是谁,
是否是登录态,这样服务端就懵逼了。cookie可以解决这个问题。如图,cookie的实现过程如下(盗了个图):

图片描述

  • 客户端向服务器发送HTTP Resuest
  • 服务器接收到请求,在返回的HTTP Response响应头中加入set-cookie字段以及对应的cookie值
  • 客户端接收到服务器的响应,解析出头部的set-cookie字段并将其中的cookie保存到本地
  • 下次向服务器发送请求时, 会将cookie附加在HTTP请求的头字段Cookie中
  • 服务器收到请求,判断cookie,便知道了发送请求的是客户端是谁了

我是一个jser,通过原生nodejs和浏览器调试工具看到每一个服务器和浏览器交互的细节。代码如下,欢迎交流并star:

https://github.com/LaputaGit/...

有兴趣的可以了解一下,运行一下代码,代码里面有详细的注释。

2、那么问题来了,你的cookie安全吗

首先,检测你的项目使用cookie有没有以下情况

  1. 能不能用js操作客户端cookie?
  2. 对于Cookie的域(Domain)和路径(Path)设置是如何制定策略的?为何这样划分?
  3. 在有SSL的应用中,你的Cookie是否可以在HTTP请求和HTTPS请求中通用?这一条暂时放放不介绍

我个人对于cookie的安全是这么理解的,我觉得cookie不是为安全而生的,所以没必要承担安全的责任,很多人拿cookie来做登录验证,包括我自己以前也这么搞过,而且搞得很简单。。。囧

来说一下cookie的安全性话题吧,谈到"为了cookie更安全",大概会做以下工作

  • 设置httpOnly为true,来保证客户端无法操作cookie
  • 设置secure为true
  • cookie在服务器以各种方式加密后,生成token

比如,用户发起登录 -> 服务器根据客户端的username, ip, expiration, useragent等组合信息,用可加密函数加密生成token,将此token保存到数据库,并将token写入cookie。

服务端验证流程: 客户端发来请求 -> 服务器解析出cookie中的token信息 -> 将token解密,验证客户端的username是否存在,如果存在 -> 验证token是否和数据库中的token相同,如果相同 -> 验证token的有效期expiration,如果有效 -> 验证ip是否变化,如果有效 -> 验证user agent等 …我们可以把很多的选项加入到cookie的加密中。

或者,有一些方案是把敏感信息交有后端session来保存,但是数据仍然放在cookie中,通过http传输

问题来了,不管你是通过cookie加密,或者是通过session包装敏感信息,这解决的是Cookie是可以被篡改的问题!这是个内部问题,可以发送HTTP请求的不只是浏览器,很多HTTP客户端软件,比如postman, paw等等,都可以发送任意的HTTP请求,可以设置任何头字段。 假如我们直接设置Cookie字段为authed=true并发送该HTTP请求, 服务器岂不是被欺骗了?这种攻击非常容易,Cookie是可以被篡改的!

但是,这样是不能保证数据的安全性的,基于HTTP的cookie的传输是明文的,可以通过抓包获取数据,这个是传输层所决定的。这个才是cookie不安全的决定因素,不管你cookie如何加密,一旦我劫持到你的cookie,再把这个cookie原封不动地发送到服务器,退一步来说,即使加密,有时也可以通过一些手段破解,只要符合服务器cookie验证的规则,那么这个cookie是"合法的",自然就不安全了。

未完待续。。。后续会补上相关代码示例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值