[ Security ] WEB安全 ( 三 ) 之 Cookie安全策略

1,032 阅读6分钟

Cookie 可能会遇到的安全风险

cookie 是什么

首先,cookies 是一段字符串,这一段字符串是存储在前端的浏览器中。他的容量很小只有 4k 。由于 HTTP 协议是一个无状态的协议,在进行通信的时候都需要一个身份凭证,而这个凭证就是写在了 cookie 中,这个是 cookie 最为常用的地方。

cookie 里面是数据是后端下发通过设置 HTTP 的 header 而实现数据写入 cookie 。浏览器在请求的时候会带上符合条件的 cookie 到达服务器进行校验。 当然,前端也是可以操作 cookie 的,但是前端操作 cookie 的目的,一般都是读取 cookie 之后把某些参数做处理或者是读取参数在某些业务场景下将参数放入 post 再去请求某些接口,前端基本上不会去修改由服务器设置的 cookie 内容。

以下是一个 cookie 的交互流程:

浏览器请求 web 登录且完成了身份认证,服务器会返回 cookie 保存同时写在浏览器中,浏览器在下次访问的时候就会带上 cookie 。

cookie 的特点

一个 cookie 里面包含的信息有,域名,有效期,路径,http-only,secure,和 samesite(google chome)。

域名

cookie 是遵循同源策略规则的,所以,cookie 只有在相同的域下才会生效。我们在日常的开发中一个 web 可能会有不同的域,但是大部分还是一样的,比如 m.ke.qq.com 和 m.bc.qq.com 这两个域的项目,那么我们可以把 cookie 的域名设置在 qq.com 域名下,这样两个网站都可以读取到这个登录态信息。当然这只是举个例子,一般也不会设置在 qq.com 的域下,因为这个域下的 web 实在太多了。

不同域的情况多数是在环境上的不同,比如开发环境和测试环境。如果引用了内部的其他部署环境那么这两个域名往往和线上的是不一样的,这个就是需要后端单独加上这个域名下的登录信息。

有效期

cookie 的有效期参数是 expire ,这里也有两种方法,第一种是写入 session ,在浏览器会话期间有效,关闭浏览器则失效。另一种是需要把 date 对象转换成字符串再写入 cookie。

let date = new Date();
let exprie = data.toGMTString();
document.cookie = `exprie=${exprie}`;

cookie 的删除并没有单独的方法,他的删除方法就是把有效期设置为一个过期的时间就可以。

路径

路径的参数是 Path,这里的意思是指定的某个路径这个 cookie 才能使用,这里的一般直接就是设置成 \ ,当前目录下都可使用,因为只要是当前域下的,其实都可以使用。

http-only

http-only 的 key 是 HttpOnly,意思就是只有在 http 的请求下才可以使用。

secure

secure 的 key 是 secure ,意思是只有在 https 的请求下才可以使用。

cookie 的作用和可能遇到的安全问题

篡改问题

cookie 最大的作用就是存储用户的登录信息,而存储的类型分为两种,第一种是前端存储用户的相关信息,比如用户的 id 。另一种是后端存储用户的相关的登录信息然后生成一个 id 下发给到浏览器。

第一种情况:将用户 id 存储在 cookie ,在用户登录之后,服务器下发用户 id 写入了浏览器的 cookie 中,下次请求再带回服务器。这里面就有一个安全的风险问题,就是人为的修改已经种下的用户 id,如果 id 被修改同时服务器有没有做其他的校验只是匹配一下用户 id 的话,那就会引发安全问题,因为这样别人就可以任意的各种操作。

而解决的方法就是,在设置用户 id 的同时,再设置一个根据用户 id 生成的一个 token 。在下一次请求服务器的时候一起带回。服务器根据请求中的 token 进行解密,最后判断是否解出 id 这个参数,如果可以就说明登录态正确,如果不行,就直接拦截操作。

他的原理就是在服务器有一个自己的密钥,别人是看不懂 cookie 设置的 id 是什么意思,只有用服务器的密钥解开才能之后加密前的数据。

可以看看具体例子,像 web qq 登录态在 cookie 中可以看到有两个参数,一个是 open_id ,另一个就是access_token。

不需要给 id 做 token 处理的就是一些业务逻辑,比如之前我开发的一个购物车组件,里面的挑选的购物元素是缓存是根据购物车的 id 缓存在本地的。这些元素就算被修改了关系也不大,因为后台是会做商品id校验,就算改了另一个还是得付钱,这个关系就不大。

第二种情况是: 将用户的登录信息存储在服务器,之后生成一个 id 下发给浏览器。这个 id 是不带有任何信息的,仅仅只是一个 id 。只是这个 id 随着请求发送到了后台,后台会根据这个id 去查找这个用户是谁。

虽然有这个方法,但是我经手的项目中却没有一个是使用这样的方法,因为这里对于服务器来说面有一个性能的问题,如果用户体量很大,那服务器就需要存储大量的 id 数据,而且,用户如果同时在多个地方登录,那是不是又要再做不同的判断处理。所以,这个方法应该是不常用的。

效果如图:

被利用信息和盗取问题

xss 和 csrf 分别就是对cookie 进行盗取和直接利用的问题,而防护的手段在前面的章节已经说明,可以查阅前两期的文章:

  • [ Security ] WEB 安全(二)之图解 CSRF 注入
  • [ Security ] WEB 安全(一)之图解 XSS 注入

安全策略

梳理一下,关于 cookie 的安全方法,就是以下几点:

  • 防止篡改
  • 后台加密
  • http-only 配置
  • secure 配置

后台加密的意思就是把信息给模糊处理,他和防止篡改有点不一样,防止篡改是数据依然是明文传送只是加了一个 token 进行解析验证的过程,而后台加密是将信息模糊加密,是别人看不懂信息的内容,只有到了服务器按自己规则解析才知道是什么。

secure 则可以防止一些窃听事件。

以上就是 cookie 相关的安全防护策略。