Cookie/Session的机制与安全

标签: cookie session 安全 | 发表时间:2015-08-10 08:00 | 作者:
出处:http://harttle.com

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响应。

    HTTP响应包括请求头和请求体两部分,可以参见: 读 HTTP 协议

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

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

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

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

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

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

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

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

  8. 过期的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)都存储在这个用户对象中。

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

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

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

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

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

相关 [cookie session 安全] 推荐:

Cookie/Session的机制与安全

- - Harttle Land
Cookie和Session是为了在无状态的HTTP协议之上维护会话状态,使得服务器可以知道当前是和哪个客户在打交道. 本文来详细讨论Cookie和Session的实现机制,以及其中涉及的安全问题. 因为HTTP协议是无状态的,即每次用户请求到达服务器时,HTTP服务器并不知道这个用户是谁、是否登录过等.

session和cookie详解

- - ITeye博客
摘要:虽然session机制在web应用程序中被采用已经很长时间了,但是仍然有很多人不清楚session机制的本质,以至不能正确的应用这一 技术. 本文将详细讨论session的工作机制并且对在Java web application中应用session机制时常见的问题作出解答. 二、HTTP协议与状态保持.

JAVA年度安全 第四周 SESSION COOKIE HTTPONLY 标识

- - Web前端 - ITeye博客
Session cookies (或者包含JSSESSIONID的cookie)是指用来管理web应用的session会话的cookies.这些cookie中保存特定使用者的session ID标识,而且相同的session ID以及session生命周期内相关的数据也在服务器端保存. 在web应用中最常用的session管理方式是通过每次请求的时候将cookies传送到服务器端来进行session识别.

说说Cookie和Session - 逝宇、

- - 博客园_首页
Session和Cookie在网站开发中是用来保存用户与后端服务器的交互状态. 而且,他们的优点和应用场景是对立的. 完整地描述:当一个用户通过HTTP访问一个服务器时,这个服务器会将一些Key/Value键值返回给客户端浏览器,并给这些数据加上一些限制条件,在条件符合时,用户下次访问这个服务器时,数据又将完整地带回给服务器.

DRP学习总结(四)---Cookie和Session

- - CSDN博客推荐文章
        图中:张三和李四分别为客户端,Tomcat为服务器. 下面我写几点体会,给大家一起品味.  1.cookie机制和session机制.         cookie机制:cookie机制采用的是在客户端保持状态的方案    .         session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息.

android WebView登录状态session id 和cookie同步

- - 移动开发 - ITeye博客
android客户端通过httpClient或者httpUrlConnection进行登录后,为了把登录状态同步到webView中,这时需要进行cookie的同步.         nvPairs.add(new BasicNameValuePair("gender", "男"));.                    //获取cookie的第一种方式.

文章: Cookie安全漫谈

- - InfoQ cn
在Web应用中,Cookie很容易成为安全问题的一部分. 从以往的经验来看,对Cookie在开发过程中的使用,很多开发团队并没有形成共识或者一定的规范,这也使得很多应用中的Cookie成为潜在的易受攻击点. 在给Web应用做安全架构评审(Security architecture review)的时候,我通常会问设计人员以下几个问题:.

你的隐私安全吗:Cookie到底是什么?

- - 博客 - 伯乐在线
这两天由于315的原因,Cookie这东西突然特别火,据说很多网友都忙着删掉自己 浏览器中的Cookie. 一开始我还觉得挺无聊的,央视不懂乱说什么啊. 直到前两天,家里一个亲戚跟我说:“原来我们上网干什么你们都知道啊,还看我们的邮件,这不一点隐私都没有了嘛. 我才意识到这个问题误导得太严重了,做为一个多年从事互联网Web开发工作的工程师,我觉得我应该说点什么.

如何保证Cookie自动登录的安全性

- - 研发管理 - ITeye博客
将用户的认证信息保证在一个cookie中,具体如下:. 推荐进行加密,比如MD5('站点名称')等. 2.cookie值:登录名|有效时间Expires|hash值. hash值可以由"登录名+有效时间Expires+用户密码(加密后的)的前几位 +salt",salt是保证在服务器端站点配置文件中的随机数.

[安全科普]你必须了解的session的本质

- - FreeBuf.COM
有一点我们必须承认,大多数web应用程序都离不开session的使用. 这篇文章将会结合php以及http协议来分析如何建立一个安全的会话管理机制. 我们先简单的了解一些http的知识,从而理解该协议的无状态特性. 然后,学习一些关于cookie的基本操作. 最后,我会一步步阐述如何使用一些简单,高效的方法来提高你的php应用程序的安全性以及稳定行.