小饼干Cookie的大魅力

小饼干Cookie的大魅力

小饼干Cookie的大魅力

  • 一、Cookie叙述-

    早期互联网只是用于简单的页面浏览,并没有交互,服务器也无法知道不同的请求是否来自同一个浏览器,不知道某用户上一次做了什么。每次请求都是相互完全独立的,这也是 HTTP 协议无状态特征的表现。这种缺陷显然无法满足交互式 Web 发展的需求,Cookie 作为一种解决这一问题的方案,被当时最强大的网景浏览器公司提出。

    一、Cookie叙述

    Cookie 可以理解成浏览器的身份证。不同站点会根据实际情况,发放一个唯一的身份证或不发放。当再次访问相同站点时,按照约定要带上这个身份证来享受部分特权。如果身份证丢了,那就要重新登记办理。

    Cookie 信息是由客户端浏览器自身维护的。不同的浏览器有不同的客户端本地存储方式,Chrome 和 Firefox 使用 SQLite 存储,IE 使用的是文本格式。Cookie 里面重要的 key&value 都是被浏览器加密存放的,只有通过给定的 API 方式才能获取存入的原始数据。默认情况下,Cookie 信息会随着浏览器进程的结束而从内存中销毁,如果由于某些需求,服务器端设置了 Cookie 的存活时间,那么这个 Cookie 就会以某种形式被存储在磁盘上,在有效存活期内不会被清理,可以被重复使用并更新其生命周期。

    1.1 观察Cookie在HTTP数据包中的交互

    这里以 http://www.website.com/bbs/ 站点为例,说明 Cookie 在 HTTP 协议包里是如何传输的。

    第一次请求 bbs 首页 /bbs/ 时,在请求数据包的 header 部分是没有 Cookie 信息的。这时,因为某些功能需要,站点会要求在浏览器本地存储 Cookies,如下面第一次交互请求登陆页面,本地浏览器会存储三个变量: phpbb3_lhc4d_u , phpbb3_lhc4d_k , phpbb3_lhc4d_sid 。在这里要重点关注 phpbb3_lhc4d_sid 这个变量,它存储的是服务器端 SessionID 的值(也可以称呼它为会话标识符)。

    GET /bbs/ HTTP/1.1
    Host: www.website.com.cn
    Upgrade-Insecure-Requests: 1
    User-Agent: Mosilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
    Referer: http://www.website.com.cn/
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
    Connection: close
    HTTP/1.1 200 OK
    Date: Mon, 21 Oct 2019 03:04:44 GMT
    Server: Apache
    X-Powered-By: PHP/5.5.38-1~dotdeb+7.1
    Set-Cookie: phpbb3_lhc4d_u=1; expires=Tue, 20-Oct-2020 03:04:44 GMT; path=/; domain=www.website.com.cn; HttpOnly
    Set-Cookie: phpbb3_lhc4d_k=; expires=Tue, 20-Oct-2020 03:04:44 GMT; path=/; domain=www.website.com.cn; HttpOnly
    Set-Cookie: phpbb3_lhc4d_sid=8fedbe0e849ab04df7a698b54d011b16; expires=Tue, 20-Oct-2020 03:04:44 GMT; path=/; domain=www.website.com.cn; HttpOnly
    Cache-Control: private, no-cache="set-cookie"
    Expires: Mon, 21 Oct 2019 03:04:44 GMT
    Referer-Policy: same-origin
    X-Frame-Options: sameorigin
    Vary: Accept-Encoding
    Content-Length: 9110
    Connection: close
    Content-Type: text/html; charset=UTF-8

    刷新页面,再次请求同一个页面,可以发现浏览器会自动把之前存储在本地的对应站点 Cookies 全部提交过去。这里提一下,每一个 Cookie 都是有大小限制的,大约在 4k 左右。

    GET /bbs/ HTTP/1.1
    Host: www.website.com.cn
    Cache-Control: max-age=0
    Upgrade-Insecure-Requests: 1
    User-Agent: Mosilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
    Referer: http://www.website.com.cn/
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
    Cookie: phpbb3_lhc4d_u=1; phpbb3_ihc4d_k=; phpbb3_lhc4d_sid=8fedbe0e849ab04df7a698b54d011b16
    Connection: close
    HTTP/1.1 200 OK
    Date: Mon, 21 Oct 2019 03:05:16 GMT
    Server: Apache
    X-Powered-By: PHP/5.5.38-1~dotdeb+7.1
    Cache-Control: private, no-cache="set-cookie"
    Expires: Mon, 21 Oct 2019 03:05:16 GMT
    Referer-Policy: same-origin
    X-Frame-Options: sameorigin
    Vary: Accept-Encoding
    Content-Length: 8435
    Connection: close
    Content-Type: text/html; charset=UTF-8

    输入正确的账号信息进入 bbs 内部后,会发现服务器更新了存储在本地 Cookie 中的 phpbb3_lhc4d_sid 信息,它是你能留在 bbs 内部板块的通行证,只要访问的时候带上这个 Cookies 就可以畅通无阻。

    POST /bbs/ucp/php?mode=login HTTP/1.1
    Host: www.website.com.cn
    Content-Length: 94
    Cache-Control: max-age=0
    Origin: http://www.website.com.cn
    Upgrade-Insecure-Requests: 1
    Content-Type: application/x-www-form-urlencoded
    User-Agent: Mosilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
    Referer: http://www.website.com.cn/bbs/
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
    Cookie: phpbb3_lhc4d_u=1; phpbb3_ihc4d_k=; phpbb3_lhc4d_sid=8fedbe0e849ab04df7a698b54d011b16
    Connection: close
    
    username=***********&password=**************************&login=%E7%99%BB%E5%BD%95&redirect=.%2Findex.php%3F
    HTTP/1.1 302 Found
    Date: Mon, 21 Oct 2019 03:05:48 GMT
    Server: Apache
    X-Powered-By: PHP/5.5.38-1~dotdeb+7.1
    Set-Cookie: phpbb3_lhc4d_u=77; expires=Tue, 20-Oct-2020 03:05:48 GMT; path=/; domain=www.website.com.cn; HttpOnly
    Set-Cookie: phpbb3_lhc4d_k=; expires=Tue, 20-Oct-2020 03:05:48 GMT; path=/; domain=www.website.com.cn; HttpOnly
    Set-Cookie: phpbb3_lhc4d_sid=bdabd760e3a87aa6b0dfb517c8c7d90a; expires=Tue, 20-Oct-2020 03:05:48 GMT; path=/; domain=www.website.com.cn; HttpOnly
    Location: http://www.website.com.cn/bbs/index.php?&sid=bdabd760e3a87aa6b0dfb517c8c7d90a
    Cache-Control: max-age=86400
    Expires: Tue, 22 Oct 2019 03:05:48 GMT
    Referer-Policy: same-origin
    X-Frame-Options: sameorigin
    Vary: Accept-Encoding
    Content-Length: 0
    Connection: close
    Content-Type: text/html
    GET /bbs/index.php HTTP/1.1
    Host: www.website.com.cn
    Upgrade-Insecure-Requests: 1
    User-Agent: Mosilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
    Referer: http://www.website.com.cn/bbs/index.php?&sid=bdabd760e3a87aa6b0dfb517c8c7d90a
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
    Cookie: phpbb3_lhc4d_u=1; phpbb3_ihc4d_k=; phpbb3_lhc4d_sid=bdabd760e3a87aa6b0dfb517c8c7d90a
    Connection: close
    HTTP/1.1 200 OK
    Date: Mon, 21 Oct 2019 03:06:16 GMT
    Server: Apache
    X-Powered-By: PHP/5.5.38-1~dotdeb+7.1
    Cache-Control: private, no-cache="set-cookie"
    Expires: Mon, 21 Oct 2019 03:06:16 GMT
    Referer-Policy: same-origin
    X-Frame-Options: sameorigin
    Vary: Accept-Encoding
    Content-Length: 37722
    Connection: close
    Content-Type: text/html; charset=UTF-8

    分析上述 HTTP 数据包的交互:

    • Cookie 是使用 HTTP 的头部来传递和交换信息的;- Set-Cookie 是服务器端给浏览器下发指令的关键字,可以带上一些控制属性;- Cookie 是浏览器端发送给服务器端消息字段,它只能是 name=value 格式,无法带上其他属性。

    二、Cookie有哪些属性

    RFC6265 中规定,通常 Set-Cookie 响应头部包含头部名称为「Set-Cookie:尾随的 Cookie」。尾随的 Cookie 除了 name, value 这两个必备属性外,还有几个其他的控制属性可选。相关描述摘录如下:

    属性描述
    必须属性变量名称:值
    可选属性描述摘录
    expires当同一个 Cookie 两次请求的 expires 值不相同时,新的可能会替换旧的。</td>
    max-age时间属性相对过期时间,以秒为单位。
    如果该属性的值不是数字,客户端将不做处理。(max-age 优先级大于 expires)
    domain
    域属性
    如果没有设置 Cookie 的 domain 值,该属性的默认值就是创建 Cookie 的网页所在的服务器域名。
    path如果服务器忽略路径属性,用户客户端会将请求 uri 路径元素的名录当做缺省值。</td>
    secure默认情况下,Cookie 是不安全的,也就是说,它们是通过一个普通的、不安全的 HTTP 链接传输的。这个属性只能保证 Cookie 是保密的。</td>
    HttpOnlyCookie 可以同时拥有 HttpOnly 以及安全属性。</td>

    三、Cookie的应用场景

    3.1 HTTP会话状态保持

    **单纯的Cookie会话管理**

    pic **相对安全的Cookie会话机制**

    pic
    在功能实现上,两者都没有问题,但在实际使用中会发现 Cookie 本身大小数量的限制和信息本地保存会带来一定的安全问题(如可能会暴露给攻击者,或被攻击者重放)。一般使用中不推荐把敏感信息存放于 Cookie 中,而是采用存储会话标识符(SessionID)到 Cookie 里的方式,服务器端可以通过获取这个会话标识符(SessionID)关联当前状态信息。当然了,使用会话标识符并非没有风险,相对于前一种方式已是个好的改善。

    打个比方,假设浏览器对应自然人,Cookie 对应身份证,而 Web 服务器端对应的是户籍管理处,那么,Web 服务器(户籍管理处)需要负责给浏览器(自然人)发放 Cookie(身份证)。后期的会话鉴别就是通过保存在客户端浏览器的 Cookie(身份证姓名和号码)里的「会话标识符」实现的,所有的敏感信息都存储在服务器端(户籍管理处),而非交给第三方的浏览器来保管。

    3.2 基于Cookie的SSO单点登录

    **同域和非同域下SSO单点登录**

    在同域下实现 Cookies 单点登录相对而言简单一些。将 Cookie 的 domain 属性配置好父域名,如 .website.com.cn ,那么这个 Cookie 就可以被类似 a.website.com.cnb.website.com.cnsso.website.com.cnwebsite.com.cn 共享使用。有一点需要特别注意,浏览器请求子域会带上父域的 Cookie,反之则不会。按照约定,我们把需要共享的 Cookie 信息写入到 website.com.cn 这个域名下即可。

    pic

    以上讨论的是同域情况下的 SSO 单点登录过程。那么跨域情况下又是怎么个原理呢?继续来看流程图,相比上述同域情况会多了跳来跳去的动作。

    pic

    3.3 跟踪分析用户行为

    「大数据」颠覆了某些旧的束缚,有能力去分析全部数据,可得出准确的大方向,而不再仅凭随机采样数据做分析。在互联网行业,「大数据」表现在采集和分析网络用户行为数据,并推送需求上。说到网络用户行为数据的采集,就不能不谈谈 Cookie 在此所扮演的另类角色。

    **客户端访问个性化设置**

    网站的各项配置参数可以存储在浏览器本地 Cookies 中,当客户端浏览器再次访问此站点时,直接通过读取 Cookies 信息即可完成相关的个性化配置。当然,局限性也很明显,Cookies 到期失效或换一台电脑,效果就没有了。这是针对临时用户而言的。有会员注册功能的站点,一般将配置保存在 Web 服务器本地数据库,这是持久存在的。

    **搜索引擎&定向广告推送**

    在搜索引擎或购物站点搜索产品信息后,再浏览其他网页时,经常在其广告区域显示曾经搜索过的产品或相关信息。哪天小伙伴借你电脑临时一用,打开游览器,你的隐私可能就暴露了,很是讨厌,而这是 Cookie 的功劳。

    pic

    **网络广告公司信息推广**

    还有一种可能,你打开的某站点很有可能还内嵌了一种叫做网页臭虫的图片。该图片透明且只有一个像素大小,我们称呼它为 Pixel Code,其作用是向所有访问过此页面的客户端写入定制的 Cookie (通过不同站点收集用户爱好习惯)。当你访问与网络广告推广有合作的购物站点时,这些 Cookie 信息就会被读取并被有针对性地推荐广告。整个流程和上面的搜索引擎&定向广告类似,在此不再作图赘述了。

    四、Cookie的安全问题探讨

    作为一个和 HTTP 协议打交道多年的安全从业者,还是忍不住想讨论下这个问题——

    我们知道 Cookie 是保存在用户本地的,由各自的浏览器自行维护。拿 Chrome 浏览器来说,用户可以直接在浏览器内输入 chrome://settings/siteData 来访问它的 Cookies 存储信息,这种方式是通过浏览器 API 获取,可以完整地看到原始 value 信息。如果用户想通过其他手段查看,还可以通过 chrome://version/ 发现数据存储的位置,仔细查看后,不难发现,%LOCALAPPDATA%\Google\Chrome\UserData\Default\Cookies 就是它的 Cookies 存储文件。这是一个 SQLite 轻型数据库,通过工具打开查询后可发现,domain 是 baidu 的都可以被搜索出来,如下图。这里可以看到,name=value 的 value 部分被浏览器进行了一次加密存储处理。

    pic

    聊完 Chrome 的本地存储,再说说 Cookie 本身的特点。Cookie 通常可能记录了用户账号 ID、密码、会话标识符 SessionID,这些信息可能是加密,也可能是未加密的。加密存储只能说明其在安全上做了些功课,但被攻击者截获(抓包、XSS)后,是否加密并无太大意义。攻击者无需看懂那串密语,只需要把这些信息照葫芦画瓢丢给服务器,就可以实现越权操作了。而这些安全性问题,可以阅读相关词条(见Ref1)了解学习。

    Ref

    1. cookie 储存在用户本地终端上的数据’ - 百科词条1. ‘HTTP State Management Mechanism’ - RFC6265
posted @ 2021-01-04 15:12  刘桓湚  阅读(61)  评论(0编辑  收藏  举报