Cookie机制:一般来说,同域内浏览器中发出的任何一个请求都会带上Cookie,无论请求什么资源,请求时,Cookie出现在请求头的Cookie字段中。服务端响应头的Set-Cookie字段可以添加、修改和删除Cookie,客户端通过javascript也可以添加、修改和删除Cookie。另外,Cookie是无法跨浏览器存在的。

利用Cookie机制,我们可以存储用户的会话信息,比如,用户登认证后的Session,之后同域内发出的请求都会带上认证后的会话信息,很方便。也因此,攻击者特别喜欢盗取Cookie,这相当于盗取了目标网站上的用户权限。

当然,有时对静态组件的Cookie读取是一种浪费,我们可以用另一个无Cookie的域名来存放这些静态组件。

Cookie的重要字段如下:

[name] [value] [domain] [path] [expries] [max-age] [httponly] [secure]

其含义依次为:名称、值、所属域名、所属相对根路径、过期时间、是否有HttpOnly标志、是否有Secure标志。

下面分别对domain、path 、httponly和secure字段进行说明:

1、子域Cookie机制

设置Cookie时,如果不指定domain的值,默认就是本域。

例如:a.foo.com域通过javascript设置一个Cookie,语句如下:

      document.cookie="test=1";

那么,domain值默认为a.foo.com。如果指定domain为父级域,比如:

      document.cookie="test=1;domain=foo.com";

此时,domain变为foo.com,这样带来一个好处就是可以在不同的子域共享Cookie,坏处也很明显,就攻击者控制的其他子域也能读到这个Cookie。注意:这个机制不允许设置Cookie的domain为下一级子域或其他外域。

2、路径Cookie机制

设置Cookie时,如果不指定path的值,默认就是目标页面的路径。

例如:a.foo.com/admin/index.php页面通过javascript来设置一个Cookie,语句如下:

      document.cookie="test=1";

那么,path值默认为/admin/。通过指定path字段,javascript可以设置任意Cookie到任意路径下,但是只有目标路径下的页面javascript才能读取到该Cookie。

但是,通过设置path不能防止重要的Cookie被盗取。比如,/evil/路径想读取/admin/路径的Cookie。通过跨iframe进行DOM操作即可做到,/evil/路径下页面的代码如下:

xc=function(src){
var o=document.createElement('iframe');//iframe进入同域的目标页面
o.src=src;
document.getElementsByTagName('body')[0].appendChild(o);
o.onload=function(){//iframe加载完成后
d=o.contentDocument||o.contentWindow.document;//获取document对象
alert(d.cookie);//获取cookie
};
}('http://a.foo.com/admin/index.php');

3、HttpOnly Cookie机制

HttpOnly是指仅在HTTP层面上传输的Cookie,当设置了HttpOnly标志后,客户端脚本就无法读写该Cookie,能有效地防御XSS攻击获取Cookie。以PHP setcookie为例,httponly.php文件代码如下:

<?php
setcookie("test",1,time()+3600,"","",0,0); //设置普通cookie
setcookie("test_http",1,time()+3600,"","",0,1);//第7个参数(这里的最后一个)是HttpOnly标志,0为关闭,1为开启,默认为0
?>

请求这个文件后,设置了个两个Cookie,如下图所示:

其中,test_http是HttpOnly Cookie。如果服务端响应的页面有Cookie调试信息,很可能会导致HttpOnly Cookie的泄漏。比如以下信息。

Apache HTTP Server2.2.x多个版本没有严格限制HTTP请求头信息,HTTP请求头超过LimitRequestFieldSize长度时,服务器返回400(Bad Request)错误并在返回信息中将出错的请求头内容输出(包含请求头里的HttpOnly Cookie),攻击者可以利用这个缺陷获取HttpOnly Cookie。

大多数浏览器限制Cookies(每个域50个Cookie)最大约为4kB,我们设置为更大且为本地Cookie,让请求头长度超过Apache的LimitRequestFieldSize,从而引起400错误。这样受攻击者只能通过清除Cookie才能正常访问目标网站。

4、Secure Cookie机制

Secure Cookie机制指的是设置了Secure标志的Cookie仅在HTTPS层面上安全传输,如果请求是HTTP的就不会带上这个Cookie,这样能降低重要的Cookie被中间人截获的风险。

但是,Secure Cookie对于客户端脚本来说是可读写的,也就意味着,它能够被盗取和篡改。如下的javascript脚本代码可对已知的Secure Cookie进行篡改:

//path与domain必须一致,否则会被认为是不同的Cookie
document.cookie="test_secure=1;path=/;secure;"

本地Cookie与内存Cookie

如果没设置过期时间,就是内存Cookie,这样的Cookie会随着浏览器的关闭而从内存中消失;如果设置了过期时间是未来的某个时间点,那么就是本地Cookie,这样的Cookie就会以文本形式保存在操作系统本地,待过期时间到了才会消失。如:

document.cookie="test_expires=1;expires=Mon,01 Jan 2112 00:00:00 GMT";//GMT时间,2112年1月1日才会过期

采用本地Cookie可以让用户在未来某一段时间内都不需要进行登录操作,提升用户体验,但是,如果攻击者通过XSS得到这样的本地Cookie后,就能够在未来很长一段时间内,甚至永久控制着目标用户的账号权限。但这并不意味着内存Cookie更安全,因为攻击者可以给内存Cookie加一个过期时间,使其变为本地Cookie。

Cookie的P3P性质

HTTP响应头的P3P(Platform for Privacy Preferences Project)字段是W3C公布的一项隐私保护推荐标准。该字段用于标识是否允许目标网站的Cookie被另一个域通过加载目标网站而设置或发送,但仅IE执行了该策略。

比如,evil域通过script或iframe等方式加载foo域。加载的时候,浏览器是否会允许foo域设置自己的Cookie,或是否允许发送请求到foo域时,带上foo域已有的Cookie。

下面是关于P3P策略在设置与发送的两个场景,P3P策略在这两个场景下是有差异的:

1、设置Cookie

在IE下,默认是不允许第三方域设置Cookie(本地和内存)的,除非foo域在响应的时候带上P3P字段,如:

P3P:CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"

该字段的内容本身意义不大,不需要记(当然我们也没有时间去记这些没有特别意义的东西),只要知道这样设置后,被加载的目标域的Cookie就可以被正常设置了,设置后的Cookie在IE下会自动带上P3P属性(这个属性在Cookie中是看不到的),一次生效,即使之后没有P3P头,也有效。

2、发送Cookie

发送的Cookie如果是内存Cookie,则无所谓是否有P3P属性,就可以正常发送;如果是本地Cookie,则这个本地Cookie必须拥有P3P属性,否则,即使目标域响应了P3P头也没用。

我们可以通过以下方法进行测试:

1)给host文件添加www.foo.com与www.evil.com域。

2)将如下代码保存为foo.php,并保证能通过www.foo.com/cookie/foo.php访问到。

<?php
//header('P3P:CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
setcookie("test0",'local',time()+3600*3650);
setcookie("test_mem0",'memory');
var_dump($_COOKIE);
?>

3)将如下代码保存为evil.php,并保证能通过www.evil.com/cookie/evil.php访问到。

<iframe src="http://www.foo.com/cookie/foo.php"></iframe>

4)IE浏览器访问www.evil.com/cookie/evil.php,由于没有响应P3P头,foo.php设置并未成功。

5)将foo.php的P3P响应功能的注释去掉,再访问www.evil.com/cookie/evil.php,可以发现本地Cookie(test0)与内存Cookie(test_mem0)都已设置成功。

6)修改foo.php里的Cookie名,比如,test0改为test1,test_mem0改为test_mem1等,注释P3P响应功能,然后直接访问www.foo.com/cookie/foo.php,这时会设置本地Cookie(test1)与内存Cookie(test_mem1),此时这两个Cookie都不带P3P属性。

7)再通过访问www.evil.com/cookie/evil.php,可以发现内存Cookie(test_mem1)正常发送,而本地Cookie(test1)没有发送。

8)继续修改foo.php里的Cookie名,test1改为test2,test_mem1改为test_mem2,去掉P3P响应功能的注释,然后直接访问www.foo.com/cookie/foo.php,此时本地Cookie(test2)与内存Cookie(test_mem2)都有了P3P属性。

9)这时访问www.evil.com/cookie/evil.php,可以发现test2与test_mem2都发送出去了。

Cookie安全小结的更多相关文章

  1. Cookie知识点小结

    问题是什么?有哪些技术?如何解决? 1. Cookie 1)完成回话跟踪的一种机制:采用的是在客户端保存Http状态信息的方案 2)Cookie是在浏览器访问WEB服务器的某个资源时,由WEB服务器在 ...

  2. cookie用法小结 cookie.setPath 跨域共享

    1. JSP中Cookie的读写 Cookie的本质是一个键值对,当浏览器访问web服务器的时候写入在客户端机器上,里面记录一些信息.Cookie还有一些附加信息,比如域名.有效时间.注释等等. 下面 ...

  3. Java EE : 二、图解 Cookie(小甜饼)

    目录 Java EE : 一.图解Http协议 Java EE : 二.图解 Cookie(小甜饼) Java EE : 三.图解Session(会话) 概述 一.概述 二.详细介绍Cookie 传输 ...

  4. 1.servlet的会话机制cookie

    会话:用户开浏览器访问某个网站,只要不关闭浏览器,不管该用户点击多少个超链接,访问多少资源,直到用户关闭浏览器,整个过程称为一次会话 cookie会话: 1.记录用户上次登录的时间 2.浏览商品的历史 ...

  5. servlet会话技术:Cookie

    什么是会话会话可以简单理解为:用户开一个浏览器访问某个网站,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话.会话过程中需要解决的一些问题每个用户在使用浏览器与服务器进 ...

  6. javaWeb学习总结(6)- 会话之cookie技术

    什么是会话? 在日常生活中,从拨通电话到挂断电话之间的一连串的你问我答的过程就是一个会话. 会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为 ...

  7. JavaEE 要懂的小事:二、图解 Cookie(小甜饼)

    Writer      :BYSocket(泥沙砖瓦浆木匠) 微         博:BYSocket 豆         瓣:BYSocket FaceBook:BYSocket Twitter   ...

  8. SESSION和cookie的使用和区别

    PHP中SESSION和cookie的使用和区别 cookie 是一种在远程浏览器端储存数据并以此来跟踪和识别用户的机制. PHP在http协议的头信息里发送cookie, 因此 setcookie( ...

  9. Session与Cookie解析

    Session和Cookie这两个对象也接触了比較长的时间了,今天就来总结一下. 首先,他们都是会话跟踪中经常使用的技术.Cookie在client记录信息来确定用户身份,Session在服务端记录信 ...

随机推荐

  1. AAA及Radius

    一.AAA(Authentication.Authorization.Accounting) 验证.授权和记费 验证 Authentication :验证用户身份 授权 Authorization : ...

  2. IFE2017笔记

    1. jQuery.trim()方法 jQuery 杂项方法 实例 删除字符串开始和末尾的空格 2.jQuery的map方法可以批量操作数组中元素,可以替代传统在循环中处理完数据挨个push进数据的代 ...

  3. 安装npm报错 npm cache clean --force 搞定

  4. php删除字符串最后一位

    一.前言 从数据库中select()读取一对多的信息时,经常需要将取出的数组用某个特定的字符分割,然后拼接成字符串. 常见的语法格式: foreach ($arr as $key => $val ...

  5. DRF 版本 及认证

    版本控制  -- # 初始化我们的版本   version, scheme = self.determine_version(request, *args, **kwargs)   request.v ...

  6. vim more

      启用鼠标 :set mouse=a 跳转到下一函数 下一个函数开头 ]] 当前函数末尾/下一个函数的末尾 ][ 当前函数开头/上一个函数的开头 [[ 选项可以按任何顺序生效,可以放在文件名前或后边 ...

  7. 逻辑卷(lv)管理(LVM)

    可以灵活改变分区大小.这里的分区叫做lv,lv创建在 vg中,vg由pv组成.pv可以由磁盘创建也可以由物理分区创建.灵活改变分区大小,就是调整lv的大小.lv可以调整的范围受到vg大小的限制,而 v ...

  8. [UGUI]图文混排(七):动态表情

    帧动画脚本: http://www.cnblogs.com/lyh916/p/9194823.html 这里的动态表情,我使用的是固定间隔去刷新Image上的Sprite来实现的,即帧动画.这里可以将 ...

  9. uva-10340-水题

    题意:字符串匹配,看样例输入理解题意 直接循环 #include <string> #include<iostream> #include<map> #includ ...

  10. replace 使用正则

    python replace正则怎么用 20 下面是我的代码:s="今天是2015年10月1日国庆节,明天是2015年10月2日"s=s.replace(r'[0-9]*', '0 ...