COOKIECOOKIE(复数形态COOKIEs),中文名称为“小型文本文件”或“小甜饼”,指某些网站为了辨别用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)COOKIE
COOKIE
COOKIE(复数形态COOKIEs),中文名称为“小型文本文件”或“小甜饼”,指某些网站为了辨别用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)COOKIE 只包含数据,就其本身而言并不有害。
分类
COOKIE总是保存在客户端中,按在客户端中的存储位置,可分为内存COOKIE和硬盘COOKIE。
内存COOKIE由浏览器维护,保存在内存中,浏览器关闭后就消失了,其存在时间是短暂的。硬盘COOKIE保存在硬盘里,有一个过期时间,除非用户手工清理或到了过期时间,硬盘COOKIE不会被删除,其存在时间是长期的。所以,按存在时间,可分为非持久COOKIE和持久COOKIE。
用途
因为HTTP协议是无状态的,即服务器不知道用户上一次做了什么,这严重阻碍了交互式Web应用程序的实现。在典型的网上购物场景中,用户浏览了几个页面,买了一盒饼干和两瓶饮料。最后结帐时,由于HTTP的无状态性,不通过额外的手段,服务器并不知道用户到底买了什么,所以COOKIE就是用来绕开HTTP的无状态性的“额外手段”之一。服务器可以设置或读取COOKIEs中包含信息,借此维护用户跟服务器会话中的状态。
在刚才的购物场景中,当用户选购了第一项商品,服务器在向用户发送网页的同时,还发送了一段COOKIE,记录着那项商品的信息。当用户访问另一个页面,浏览器会把COOKIE发送给服务器,于是服务器知道他之前选购了什么。用户继续选购饮料,服务器就在原来那段COOKIE里追加新的商品信息。结帐时,服务器读取发送来的COOKIE就行了。
COOKIE另一个典型的应用是当登录一个网站时,网站往往会请求用户输入用户名和密码,并且用户可以勾选“下次自动登录”。如果勾选了,那么下次访问同一网站时,用户会发现没输入用户名和密码就已经登录了。这正是因为前一次登录时,服务器发送了包含登录凭据(用户名加密码的某种加密形式)的COOKIE到用户的硬盘上。第二次登录时,如果该COOKIE尚未到期,浏览器会发送该COOKIE,服务器验证凭据,于是不必输入用户名和密码就让用户登录了。
COOKIE的缺陷
- COOKIE会被附加在每个HTTP请求中,所以无形中增加了流量。
- 由于在HTTP请求中的COOKIE是明文传递的,所以安全性成问题,除非用HTTPS。
- COOKIE的大小限制在4KB左右,对于复杂的存储需求来说是不够用的
使用COOKIEs
用户可以改变浏览器的设置,以使用COOKIEs。同时一些浏览器自带或安装开发者工具包允许用户查看、修改或删除特定网站的COOKIEs信息。
反对COOKIEs者
一些人反对COOKIEs在网络中的应用,他们的理由如下:
识别不精确
如果在同一台机器上使用多个浏览器,每个浏览器在不同的存储位置保存 COOKIE,因此,COOKIE 并不能定位到一个具体的人,而是用户,计算机和浏览器的组合。
不确定的状态
如果用户在获取了一个 COOKIE 之后,点击了浏览器的"回退"按键,则浏览器的状态和获取COOKIE 的状态就出现了不一致.例如, 如果网站基于 COOKIE 技术实现了购物车的应用,当用户添加了物品后点击了"回退"按键, 购物车的物品状态可能并没有发生变化.
隐私、安全和广告
COOKIEs在某种程度上说已经严重危及用户的隐私和安全。其中的一种方法是:一些公司的高层人员为了某种目的(譬如市场调研)而访问了从未去过的网站(通过搜索引擎查到的),而这些网站包含了一种叫做网页臭虫的图片,该图片透明,且只有一个像素大小(以便隐藏),它们的作用是将所有访问过此页面的计算机写入COOKIE。而后,电子商务网站将读取这些COOKIE信息,并寻找写入这些COOKIE的网站,随即发送包含了针对这个网站的相关产品广告的垃圾邮件给这些高级人员。
偷窃COOKIEs和脚本攻击
虽然COOKIEs没有中电脑病毒那么危险,但它仍包含了一些敏感消息:用户名、电脑名、使用的浏览器和曾经访问的网站。用户不希望这些内容泄漏出去,尤其是当其中还包含有私人信息的时候。
这并非危言耸听,跨站点脚本(Cross site scripting)可以达到此目的。在受到跨站点脚本攻击时,COOKIE盗贼和COOKIE毒药将窃取内容。一旦COOKIE落入攻击者手中,它将会重现其价值。
- COOKIE盗贼:搜集用户COOKIE并发给攻击者的黑客,攻击者将利用COOKIE消息通过合法手段进入用户帐户。
- COOKIE投毒:一般认为,COOKIE在储存和传回服务器期间没有被修改过,而攻击者会在COOKIE送回服务器之前对其进行修改,达到自己的目的。例如,在一个购物网站的COOKIE中包含了顾客应付的款项,攻击者将该值改小,达到少付款的目的。
Set-COOKIE HTTP响应头的语法
这是CGI脚本用于向HTTP标头添加新数据的格式,该数据将由客户端存储以供以后检索。
Set-COOKIE:NAME =VALUE ; 到期=DATE ;
path =PATH ; domain =DOMAIN_NAME ; 安全
NAME = VALUE
此字符串是一系列字符,不包括分号,逗号和空格。如果需要在名称或值中放置此类数据,则建议使用某种编码方法,例如URL样式%XX编码,但不定义或要求编码。
这是Set-COOKIE标头上唯一必需的属性。
到期 = DATE
在到期属性指定,它定义了COOKIE的有效续航时间日期字符串。达到到期日后,将不再存储或发放COOKIE。
日期字符串的格式为:
Wdy,DD-Mon-YYYY HH:MM:SS GMT
expires是一个可选属性。如果未指定,则COOKIE将在用户会话结束时到期。
注意: Netscape Navigator 1.1及更早版本中存在错误。只有路径属性明确设置为“/”的COOKIE 才会在会话之间正确保存(如果它们具有expires 属性)。
domain = DOMAIN_NAME
在COOKIE列表中搜索有效的COOKIE时, 将使用从中获取URL的主机的Internet域名来比较COOKIE的 域属性。如果存在尾部匹配,则COOKIE将通过路径匹配以查看是否应该发送。“尾部匹配”表示域属性与主机的完全限定域名的尾部匹配。一域 “acme.com”的属性将匹配主机名“anvil.acme.com”以及“shipping.crate.acme.com”。
只有指定域中的主机可以为域设置COOKIE,域中必须至少有两(2)或三(3)个句点才能阻止表单域:“。com”,“。hadu”和“ va.us”。在下面列出的七个特殊顶级域之一中失败的任何域只需要两个句点。任何其他域名至少需要三个。七个特殊的顶级域名是:“COM”,“EDU”,“NET”,“ORG”,“GOV”,“MIL”和“INT”。
domain 的默认值是生成COOKIE响应的服务器的主机名。
path = PATH
的路径属性用来指定的量,COOKIE有效的域的URL的子集。如果COOKIE已经通过域 匹配,则将URL的路径名组件与路径属性进行比较,如果匹配,则认为COOKIE有效并与URL请求一起发送。路径“/ foo”将匹配“/ foobar”和“/foo/bar.html”。路径“/”是最常用的路径。
如果未指定路径,则假定它与包含COOKIE的标题所描述的文档的路径相同。
安全
如果COOKIE被标记为安全,则只有在与主机的通信通道是安全通道时才会传输。目前,这意味着安全COOKIE只会发送到HTTPS(HTTP over SSL)服务器。
如果未指定安全,则认为COOKIE可以安全地通过不安全的通道发送。
COOKIE HTTP请求标头的语法
从HTTP服务器请求URL时,浏览器将针对所有COOKIE匹配URL,如果其中任何一个匹配,则包含所有匹配COOKIE的名称/值对的行将包含在HTTP请求中。这是该行的格式:
COOKIE:NAME1 = OPAQUE_STRING1 ;NAME2 = OPAQUE_STRING2 ......
第一个示例事物序列
客户端请求文档,并在响应中接收:
Set-COOKIE:CUSTOMER = WILE_E_COYOTE; 路径= /; 到期=星期三,09-Nov-99 23:12:40 GMT
当客户端在此服务器上请求路径“/”中的URL时,它会发送:
COOKIE:CUSTOMER = WILE_E_COYOTE
客户端请求文档,并在响应中接收:
Set-COOKIE:PART_NUMBER = ROCKET_LAUNCHER_0001; 路径= /
当客户端在此服务器上请求路径“/”中的URL时,它会发送:
COOKIE:CUSTOMER = WILE_E_COYOTE; PART_NUMBER = ROCKET_LAUNCHER_0001
客户收到:
Set-COOKIE:SHIPPING = FEDEX; 路径= /富
当客户端在此服务器上请求路径“/”中的URL时,它会发送:
COOKIE:CUSTOMER = WILE_E_COYOTE; PART_NUMBER = ROCKET_LAUNCHER_0001
当客户端在此服务器上请求路径“/ foo”中的URL时,它会发送:
COOKIE:CUSTOMER = WILE_E_COYOTE; PART_NUMBER = ROCKET_LAUNCHER_0001; 运费= FEDEX
第二个示例事务序列
假设已清除上面的所有映射。
客户收到:
Set-COOKIE:PART_NUMBER = ROCKET_LAUNCHER_0001; 路径= /
当客户端在此服务器上请求路径“/”中的URL时,它会发送:
COOKIE:PART_NUMBER = ROCKET_LAUNCHER_0001
客户收到:
Set-COOKIE:PART_NUMBER = RIDING_ROCKET_0023; 路径= /弹药
当客户端在此服务器上请求路径“/ ammo”中的URL时,它会发送:
COOKIE:PART_NUMBER = RIDING_ROCKET_0023; PART_NUMBER = ROCKET_LAUNCHER_0001
注意:由于除了“/ ammo”映射之外还继承了“/”映射,因此有两个名为“PART_NUMBER”的名称/值对。
COOKIE的实现原理
COOKIE定义了一些HTTP请求头和HTTP响应头,通过这些HTTP头信息使服务器可以与客户进行状态交互。
客户端请求服务器后,如果服务器需要记录用户状态,服务器会在响应信息中包含一个Set-COOKIE的响应头,客户端会根据这个响应头存储COOKIE信息。再次请求服务器时,客户端会在请求信息中包含一个COOKIE请求头,而服务器会根据这个请求头进行用户身份、状态等较验。
1. 客户端请求服务器
客户端请求IT笔录网站首页,请求头如下:
GET / HTTP/1.0
HOST: itbilu.com
2. 服务器响应请求
COOKIE是一种key=value形式的字符串,服务器需要记录这个客户端请求的状态,因此在响应头中包一个Set-COOKIE字段。响应头如下:
HTTP/1.0 200 OK
Set-COOKIE: UserID=itbilu; Max-Age=3600; Version=1
Content-type: text/html
……
3. 再次请求时,客户端请求中会包含一个COOKIE请求头
客户端会对服务器响应的Set-COOKIE头信息进行存储。再次请求时,将会在请求头中包含服务器响应的COOKIE信息。请求头如下
GET / HTTP/1.0
HOST: itbilu.com
COOKIE: UserID=itbilu
COOKIE的安全注意点
Httponly:防止COOKIE被xss偷
https:防止COOKIE在网络中被偷
Secure:阻止COOKIE在非https下传输,很多全站https时会漏掉
Path :区分COOKIE的标识,安全上作用不大,和浏览器同源冲突
HttpOnly的作用
要理解HttpOnly的作用,要先弄懂XSS攻击,即跨站脚本攻击
某同学提交了一个意见,但是内容中包含了一段恶意Javascript脚本,服务端没有做任何处理。就会运行那段Javascript脚本
解决这个问题,可以从两方面着手
- 1)服务端对提交上来的留言内容做过滤,把恶意代码过滤掉
- 2)让恶意Javascript代码读取不到我们种的COOKIE
HttpOnly的COOKIE就是从第二点解决方案着手的,COOKIE是通过http response header种到浏览器的,我们来看看设置COOKIE的语法:
Set-COOKIE:=[; <Max-Age>=][; expires=][; domain=][; path=][; secure][;HttpOnly]
是一个name=value的KV,然后是一些属性,比如失效时间,作用的domain和path,最后还有两个标志位,可以设置为secure和HttpOnly,所以,我们只要加一个;HttpOnly的标志即可,比如:
Set-Cookie: USER=Ulric-UlricPass; expires=Wednesday,09-Nov-99 3:12:40 GMT;HttpOnly
这样一来,Javascript就读取不到这个COOKIE信息了,不过在与服务端交互的时候,Http Request包中仍然会带上这个COOKIE信息,即我们的正常交互不受影响。
Https的作用
防止COOKIE在网络中被偷 目前主流网站的认证COOKIE在互联网中都是无保护进行传输的,可能会在网络中被嗅探或其他方式泄露。所以建议安全级别高的网站使用全站https,并且不支持http的访问,而且还要使用HSTS,强制把http的请求转成https请求
当混用http和https时,firefox、chrome、ie8都可以正常读取COOKIE
https协议下,浏览器默认不会加载页面中的http请求(图片会正常加载,js和css不加载)。可以不写明具体的协议只写两个斜杠,即用//代替http://和https://,这样浏览器加载的时候会自动匹配当前页面的协议。这也是Google HTML/CSS Style Guide推荐的方式。
总结:
COOKIE的安全策略和Javascript的同源策略并不完全相同,COOKIE只受Domian、Path、Expires、HttpOnly、Secure等属性的影响。
COOKIE的传输并不受端口限制。
当COOKIE属性secure设置为true时,COOKIE只能在https中传输,http不会传输。
secure的作用
Secure和HttpOnly属性没有关联的值。相当于只要显示了他们的属性名就表示支持他们的行为。
Secure属性意味着把COOKIE通信限制在加密传输中,指示浏览器只能通过安全/加密连接使用COOKIE。然而如果一个web服务器在非安全连接中给COOKIE设置了一个secure属性,这个COOKIE在发送给用户时仍然可以通过中间人攻击拦截到。因此,为了安全必须通过安全连接设置COOKIE的Secure属性
当属性值为true时,表示创建的COOKIE会被以安全的形式向服务器传输,也就是只能在HTTPS连接中被浏览器传递到服务器端进行会话验证,如果是HTTP连接则不会传递该信息,所以不会被窃取到COOKIE的具体内容
Path的作用
区分COOKIE的标识,安全上作用不大,和浏览器同源冲突 COOKIE还有一个path属性,这是一个区分COOKIE的标识,安全上作用不大,和浏览器同源策略冲突。因为,路径A下的xss虽然读不到路径B下的COOKIE,但路径A下的xss完全可以注入代码进入路径B的页面,然后再去读路径B下的COOKIE