标签:
Cookie(复数形态Cookies),中文名称为小型文本文件或小甜饼,指某些网站为了辨别用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。定义于RFC2109。是网景公司的前雇员Lou Montulli在1993年3月的发明。
概念:Cookie是web server下发给浏览器的任意的一段文本。在后续的http 请求中,浏览器会将cookie带回给Web Server。
因为HTTP协议是无状态的,即服务器不知道用户上一次做了什么,这严重阻碍了交互式Web应用程序的实现。
在典型的网上购物场景中,用户浏览了几个页面,买了一盒饼干和两瓶饮料。最后结帐时,由于HTTP的无状态性,不通过额外的手段,服务器并不知道用户到底买了什么。 所以Cookie就是用来绕开HTTP的无状态性的“额外手段”之一。服务器可以设置或读取Cookies中包含信息,借此维护用户跟服务器会话中的状态。
在刚才的购物场景中,当用户选购了第一项商品,服务器在向用户发送网页的同时,还发送了一段Cookie,记录着那项商品的信息。当用户访问另一个页面,浏览器会把Cookie发送给服务器,于是服务器知道他之前选购了什么。用户继续选购饮料,服务器就在原来那段Cookie里追加新的商品信息。结帐时,服务器读取发送来的Cookie就行了。
每次访问都像第一次访问一样,无法判断用户是否访问过
任何的购买等交互、验证行为都必须在一次访问中完成
无任何记忆,均需要用户重新点击或填写
这个应该很好理解,一个是存在内存,一个存在硬盘。区别就在于Cookie的有效时间。
内存Cookie:由浏览器维护,保存在内存中,浏览器关闭后就消失了,其存在时间是短暂的。
硬盘Cookie:保存在硬盘里,有一个过期时间,除非用户手工清理或到了过期时间,硬盘Cookie不会被删除,其存在时间是长期的。
登录一个网站时,网站往往会请求用户输入用户名和密码,并且用户可以勾选“下次自动登录”。如果勾选了,那么下次访问同一网站时,用户会发现没输入用户名和密码就已经登录了。这正是因为前一次登录时,服务器发送了包含登录凭据(用户名加密码的某种加密形式)的Cookie到用户的硬盘上。第二次登录时,(如果该Cookie尚未到期)浏览器会发送该Cookie,服务器验证凭据,于是不必输入用户名和密码就让用户登录了。
这个类型的cookie只在会话期间内有效,即当关闭浏览器的时候,它会被浏览器删除。设置session cookie的办法是:在创建cookie不设置Expires即可。
持久型cookie顾名思义就是会长期在用户会话中生效。当你设置cookie的属性Max-Age为1个月的话,那么在这个月里每个相关URL的http请求中都会带有这个cookie。所以它可以记录很多用户初始化或自定义化的信息,比如什么时候第一次登录及弱登录态等。
安全cookie是在https访问下的cookie形态,以确保cookie在从客户端传递到Server的过程中始终加密的。这样做大大的降低的cookie内容直接暴露在黑客面前及被盗取的概率。
目前主流的浏览器已经都支持了httponly cookie。1.IE5+ 2.Firefox 1.0+ 3.Opera 8.0+ 4.Safari/Chrome。在支持httponly的浏览器上,设置成httponly的cookie只能在http(https)请求上传递。也就是说httponly cookie对客户端脚本语言(javascript)无效,从而避免了跨站攻击时JS偷取cookie的情况。当你使用javascript在设置同样名字的cookie时,只有原来的httponly值会传送到服务器。
第一方cookie是cookie种植在浏览器地址栏的域名或子域名下的。第三方cookie则是种植在不同于浏览器地址栏的域名下。例如:用户访问a.com时,在ad.google.com设置了个cookie,在访问b.com的时候,也在ad.google.com设置了一个cookie。这种场景经常出现在google adsense,阿里妈妈之类的广告服务商。广告商就可以采集用户的一些习惯和访问历史。
超级cookie是设置公共域名前缀上的cookie。通常a.b.com的cookie可以设置在a.b.com和b.com,而不允许设置在.com上,但是很不幸的是历史上一些老版本的浏览器因为对新增后缀过滤不足导致过超级cookie的产生。
以访问本站(www.kryptosx.info)为例。
这里使用Fiddler来进行HTTP抓包,用来分析交互时的Cookie是如何传递的。
使用浏览器打开www.kryptosx.info,这是一个GET请求。
可以看出,第一次请求中,并没有Cookies的信息,但是返回包中,有Set-Code头,后面跟着的就是Cookies信息。
从图中可以看出,三个都是删除Cookie的—“=deleted”。Cookies是httponly的。另外,expires设置为1970年,这个cookie就成了所谓的session-cookie。因为浏览器会自动清理掉过期的Cookies。
这次依然是GET请求,但是带上了Cookie。
GET / HTTP/1.1 Accept: text/html, application/xhtml+xml, */* Accept-Language: zh-Hans-CN,zh-Hans;q=0.8,en-US;q=0.5,en;q=0.3 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko Accept-Encoding: gzip, deflate Host: www.kryptosx.info DNT: 1 Connection: Keep-Alive Cookie: CNZZDATA1254085044=1980544601-1431063029-%7C1431063029
当然,返回包也带了Cookie。
从抓包中,可以看出HTTP交互时传递Cookies的方式。当然,我这里这个Cookie估计是访问统计的。
Cookies是一个浏览器和服务器交互的,并非依赖于单个网页。浏览器是对通过域来区分的。通过信息的附带我们也可以看得出,它和Post还是GET并无关系。
Cookies可以被看作是一个凭据,自然会被骇客窥视。只要窃取了它,攻击者就能冒充你的身份了。
可能某天,你收到一封邮件,它告诉你,你的XXX网账号有风险,请立刻修改。里面还有个链接,你发现链接没错,确实是XXX网的域名。你可能没注意,直接点开了。之后,你就发现你的XXX系统中的密码被改掉了。
这就是一个CSRF攻击,攻击者精心设计了一个网址。这个网址就附带了更改密码的GET请求。另外你的浏览器本地保存着XXX网的Cookies,所以操作是合法的。
CSRF还有别的手段,比如在某个网页里嵌入图片等,这类更为隐蔽。
CSRF看上去很可怕,但还是能解决的。当然这种东西不能靠用户,还是要网站开发者来搞定。
CSRF利用的是Cookies的特点,因为Cookies是浏览器级别的一个信息,同一个浏览器登录相同的网站的不同网页都能访问相同的Cookies。因此攻击者的请求对于浏览器来说是合法的,服务端没有做CSRF保护,也认为这个请求是合法,这样就被攻击了。
前面说了,Cookies是一个凭证,但是Cookies是浏览器级别的,同个浏览器都能用这个凭证,因此黑客也能利用。那我们能不能弄一个凭证,让黑客没法利用,不就解决了,接着这个例子,合法的修改密码操作是会先打开修改密码页面,输完要修改的密码,然后点击提交。而黑客是直接提交请求的,并没有打开修改密码页面这一步。
所以,目前防CSRF攻击的方法,大多都是在网页中加入一个Token,即把一个凭证放到页面里,这是页面级别的,黑客没法利用这个凭证,CSRF攻击也就难以进行了。
也有使用验证码的,这个当然更安全,此外,还有防暴力破解的能力,但是用户体验不大好。所以一般放在重要操作中,比如改密码这类:P。
另外,有人说用了Post就安全,Post相对GET而言确实要好点,毕竟伪造Post难度大点。但是千万别认为就能躲开CSRF了。JS脚本是能模拟Post请求的。所以该加Token还是加Token吧。
参考资料:http://www.webryan.net/2011/08/wiki-of-http-cookie/
标签:
原文地址:http://my.oschina.net/u/2350108/blog/531033