Cookie(复数形态Cookies),中文名称为小型文本文件或小甜饼,指某些网站为了辨别用户身份而储存在用户本地终端(Client Side)上的数据(一般通过加密)。定义于RFC2109。是网景公司的前雇员Lou Montulli在1993年3月的发明。javascript
概念:Cookie是web server下发给浏览器的任意的一段文本。在后续的http 请求中,浏览器会将cookie带回给Web Server。html
由于HTTP协议是无状态的,即服务器不知道用户上一次作了什么,这严重阻碍了交互式Web应用程序的实现。java
在典型的网上购物场景中,用户浏览了几个页面,买了一盒饼干和两瓶饮料。最后结账时,因为HTTP的无状态性,不经过额外的手段,服务器并不知道用户到底买了什么。 因此Cookie就是用来绕开HTTP的无状态性的“额外手段”之一。服务器能够设置或读取Cookies中包含信息,借此维护用户跟服务器会话中的状态。web
在刚才的购物场景中,当用户选购了第一项商品,服务器在向用户发送网页的同时,还发送了一段Cookie,记录着那项商品的信息。当用户访问另外一个页面,浏览器会把Cookie发送给服务器,因而服务器知道他以前选购了什么。用户继续选购饮料,服务器就在原来那段Cookie里追加新的商品信息。结账时,服务器读取发送来的Cookie就好了。浏览器
每次访问都像第一次访问同样,没法判断用户是否访问过安全
任何的购买等交互、验证行为都必须在一次访问中完成服务器
无任何记忆,均须要用户从新点击或填写cookie
这个应该很好理解,一个是存在内存,一个存在硬盘。区别就在于Cookie的有效时间。session
内存Cookie:由浏览器维护,保存在内存中,浏览器关闭后就消失了,其存在时间是短暂的。app
硬盘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/