Cookie和Session是为了在无状态的HTTP协议之上维护会话状态,使得服务器可以知道当前是和哪个客户在打交道。本文来详细讨论Cookie和Session的实现机制,以及其中涉及的安全问题。

因为HTTP协议是无状态的,即每次用户请求到达服务器时,HTTP服务器并不知道这个用户是谁、是否登录过等。现在的服务器之所以知道我们是否已经登录,是因为服务器在登录时设置了浏览器的Cookie!Session则是借由Cookie而实现的更高层的服务器与浏览器之间的会话。

Cookie是由网景公司的前雇员Lou Montulli在1993年发明的,现今Cookie已经广泛使用了。

Cookie 的实现机制

Cookie是由客户端保存的小型文本文件,其内容为一系列的键值对。 Cookie是由HTTP服务器设置的,保存在浏览器中, 在用户访问其他页面时,会在HTTP请求中附上该服务器之前设置的Cookie。 Cookie的实现标准定义在RFC2109: HTTP State Management Mechanism中。 那么Cookie是怎样工作的呢?下面给出整个Cookie的传递流程:

  1. 浏览器向某个URL发起HTTP请求(可以是任何请求,比如GET一个页面、POST一个登录表单等)

  2. 对应的服务器收到该HTTP请求,并计算应当返回给浏览器的HTTP响应。

  3. 在响应头加入Set-Cookie字段,它的值是要设置的Cookie。

RFC2109 6.3 Implementation Limits中提到: UserAgent(浏览器就是一种用户代理)至少应支持300项Cookie, 每项至少应支持到4096字节,每个域名至少支持20项Cookie。

  1. 浏览器收到来自服务器的HTTP响应。

  2. 浏览器在响应头中发现Set-Cookie字段,就会将该字段的值保存在内存或者硬盘中。

Set-Cookie字段的值可以是很多项Cookie,每一项都可以指定过期时间Expires。 默认的过期时间是用户关闭浏览器时。

  1. 浏览器下次给该服务器发送HTTP请求时, 会将服务器设置的Cookie附加在HTTP请求的头字段Cookie中。

浏览器可以存储多个域名下的Cookie,但只发送当前请求的域名曾经指定的Cookie, 这个域名也可以在Set-Cookie字段中指定)。

  1. 服务器收到这个HTTP请求,发现请求头中有Cookie字段, 便知道之前就和这个用户打过交道了。

  2. 过期的Cookie会被浏览器删除。

总之,服务器通过Set-Cookie响应头字段来指示浏览器保存Cookie, 浏览器通过Cookie请求头字段来告诉服务器之前的状态。 Cookie中包含若干个键值对,每个键值对可以设置过期时间。

Cookie 的安全隐患

Cookie提供了一种手段使得HTTP请求可以附加当前状态, 现今的网站也是靠Cookie来标识用户的登录状态的:

  1. 用户提交用户名和密码的表单,这通常是一个POST HTTP请求。

  2. 服务器验证用户名与密码,如果合法则返回200(OK)并设置Set-Cookieauthed=true

  3. 浏览器存储该Cookie。

  4. 浏览器发送请求时,设置Cookie字段为authed=true

  5. 服务器收到第二次请求,从Cookie字段得知该用户已经登录。 按照已登录用户的权限来处理此次请求。

这里面的问题在哪里?

我们知道可以发送HTTP请求的不只是浏览器,很多HTTP客户端软件(包括curl、Node.js)都可以发送任意的HTTP请求,可以设置任何头字段。 假如我们直接设置Cookie字段为authed=true并发送该HTTP请求, 服务器岂不是被欺骗了?这种攻击非常容易,Cookie是可以被篡改的!

Cookie 防篡改机制

服务器可以为每个Cookie项生成签名,由于用户篡改Cookie后无法生成对应的签名, 服务器便可以得知用户对Cookie进行了篡改。一个简单的校验过程可能是这样的:

  1. 在服务器中配置一个不为人知的字符串(我们叫它Secret),比如:x$sfz32

  2. 当服务器需要设置Cookie时(比如authed=false),不仅设置authed的值为false, 在值的后面进一步设置一个签名,最终设置的Cookie是authed=false|6hTiBl7lVpd1P

  3. 签名6hTiBl7lVpd1P是这样生成的:Hash('x$sfz32'+'true')。 要设置的值与Secret相加再取哈希。

  4. 用户收到HTTP响应并发现头字段Set-Cookie: authed=false|6hTiBl7lVpd1P

  5. 用户在发送HTTP请求时,篡改了authed值,设置头字段Cookie: authed=true|???。 因为用户不知道Secret,无法生成签名,只能随便填一个。

  6. 服务器收到HTTP请求,发现Cookie: authed=true|???。服务器开始进行校验:Hash('true'+'x$sfz32'),便会发现用户提供的签名不正确。

通过给Cookie添加签名,使得服务器得以知道Cookie被篡改。然而故事并未结束。

因为 Cookie是明文传输的, 只要服务器设置过一次authed=true|xxxx我不就知道true的签名是xxxx了么, 以后就可以用这个签名来欺骗服务器了。因此Cookie中最好不要放敏感数据。 一般来讲Cookie中只会放一个Session Id,而Session存储在服务器端。

Session 的实现机制

Session 是存储在服务器端的,避免了在客户端Cookie中存储敏感数据。 Session 可以存储在HTTP服务器的内存中,也可以存在内存数据库(如redis)中, 对于重量级的应用甚至可以存储在数据库中。

我们以存储在redis中的Session为例,还是考察如何验证用户登录状态的问题。

  1. 用户提交包含用户名和密码的表单,发送HTTP请求。

  2. 服务器验证用户发来的用户名密码。

  3. 如果正确则把当前用户名(通常是用户对象)存储到redis中,并生成它在redis中的ID。

这个ID称为Session ID,通过Session ID可以从Redis中取出对应的用户对象, 敏感数据(比如authed=true)都存储在这个用户对象中。

  1. 设置Cookie为sessionId=xxxxxx|checksum并发送HTTP响应, 仍然为每一项Cookie都设置签名。

  2. 用户收到HTTP响应后,便看不到任何敏感数据了。在此后的请求中发送该Cookie给服务器。

  3. 服务器收到此后的HTTP请求后,发现Cookie中有SessionID,进行放篡改验证。

  4. 如果通过了验证,根据该ID从Redis中取出对应的用户对象, 查看该对象的状态并继续执行业务逻辑。

Web应用框架都会实现上述过程,在Web应用中可以直接获得当前用户。 相当于 在HTTP协议之上,通过Cookie实现了持久的会话。这个会话便称为Session

原文出处:http://harttle.com/2015/08/10/cookie-session.html

[转载]Cookie/Session的机制与安全的更多相关文章

  1. Cookie/Session的机制与安全

    转载自:https://harttle.land/2015/08/10/cookie-session.html Cookie和Session是为了在无状态的HTTP协议之上维护会话状态,使得服务器可以 ...

  2. Cookie/Session的机制

    Cookie的机制 Cookie是浏览器(User Agent)访问一些网站后,这些网站存放在客户端的一组数据,用于使网站等跟踪用户,实现用户自定义功能. Cookie的Domain和Path属性标识 ...

  3. (转载)session token机制

    http://blog.chinaunix.net/uid-26642709-id-3061264.html 使用session token时,必须用struts2表标签库,不能用html 通过ses ...

  4. [06] Session实现机制以及和Cookie的区别

    1.为什么有Session和Cookie 根据早期的HTTP协议,每次request-reponse时,都要重新建立TCP连接.TCP连接每次都重新建立,所以服务器无法知道上次请求和本次请求是否来自于 ...

  5. 【转】Cookie/Session机制详解

    Cookie/Session机制详解   会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息 ...

  6. Chrome的cookie放在哪里了,Cookie/Session机制详解

    Chrome的cookie放在哪里了,Cookie/Session机制详解:https://blog.csdn.net/u010002184/article/details/82082951

  7. 第十一篇 session和cookie自动登录机制

    session和cookie的作用和区别可以在网上查到,这里简单说下,我们使用的http协议本身是种无状态的协议,就是说web服务器接收到浏览器的请求,会直接返回相应内容,并不会检查是哪个浏览器,即浏 ...

  8. atitit. access token是什么??微信平台公众号开发access_token and Web session保持状态机制

    atitit. access token是什么??微信平台公众号开发access_token and Web session保持状态机制 1. token机制and  session保持状态机制 1 ...

  9. Session执行机制与原理

    Session执行机制与原理 作者:Stanley 罗昊 [转载请注明出处和署名,谢谢!] 什么是Session 首先了解一下Session的中文意思:一次会话,什么是一次会话呢?我举个例子:就我们现 ...

随机推荐

  1. H5实现摇一摇技术总结

    摇一摇遇到的问题 一.如何对摇晃效果进行反馈 刚开始的处理方式是,摇晃过程中不做任何处理,但后来反馈说这种效果不好,好像就没有摇动一样,如果声音也不响的话,就真的和什么都没发生一样. 后来想了想,加入 ...

  2. ASP.NET Core 折腾笔记一

    前言: 在ASP.NET Core 1.0时,曾折腾过一次,后因发现不了System.Data而停止. 更因VS2015提示过期Delete掉VS了,其实主要还是笔记本的硬盘空间吃紧. 快双十一了,本 ...

  3. eclipse 快捷键大全

    注:因eclipse版本.电脑配置等原因 有些快捷键可能导致不可用(遇到些许问题可在下方评论) [Ct rl+T] 搜索当前接口的实现类 1. [ALT +/]    此快捷键为用户编辑的好帮手,能为 ...

  4. Objective-C三种定时器CADisplayLink / NSTimer / GCD的使用

    OC中的三种定时器:CADisplayLink.NSTimer.GCD 我们先来看看CADiskplayLink, 点进头文件里面看看, 用注释来说明下 @interface CADisplayLin ...

  5. Win10 IIS本地部署MVC网站时不能运行?

    异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 部署后出现这个错误: 打开文件目录后发现是可以看见目录的,静态页面也是可以打开的 ...

  6. 【Win 10 应用开发】在App所在的进程中执行后台任务

    在以往版本中,后台任务都是以独立的专用进程来运行,因此,定义后台任务代码的类型都要位于 Windows 运行时组件项目中. 不过,在14393中,SDK 作了相应的扩展,不仅支持以前的独立进程中运行后 ...

  7. iOS开发之Masonry框架源码深度解析

    Masonry是iOS在控件布局中经常使用的一个轻量级框架,Masonry让NSLayoutConstraint使用起来更为简洁.Masonry简化了NSLayoutConstraint的使用方式,让 ...

  8. Mac OS、Ubuntu 安装及使用 Consul

    Consul 概念(摘录): Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其他分布式服务注册与发现的方案,比如 Airbnb 的 SmartStac ...

  9. C#中如何给Excel添加水印

    我们知道Microsoft Excel并没有内置的功能直接给Excel表添加水印,但是其实我们可以用其他变通的方式来解决此问题,如通过添加页眉图片或艺术字的方法来模仿水印的外观.所以在这篇文章中,我将 ...

  10. C#制作简易屏保

    前言:前段时间,有个网友问我C#制作屏保的问题,我瞬间懵逼了(C#还可以制作屏保!).于是我去查阅相关资料,下面把C#如何制作屏保的过程及我学习过程的心得也记录下来,希望对需要的人能有帮助. 基本思路 ...