一、Cookie,Session,Token简介
# 这三者都解决了HTTP协议无状态的问题
session ID or session token is a piece of data that is used in network communications (often over HTTP) to identify a session, a series of related message exchanges. Session identifiers become necessary in cases where the communications infrastructure uses a stateless protocol such as HTTP. For example, a buyer who visits a seller's site wants to collect a number of articles in a virtual shopping cart and then finalize the shopping by going to the site's checkout page. This typically involves an ongoing communication where several webpages are requested by the client and sent back to them by the server. In such a situation, it is vital to keep track of the current state of the shopper's cart, and a session ID is one way to achieve that goal.
A session ID is typically granted to a visitor on his first visit to a site. It is different from a user ID in that sessions are typically short-lived (they expire after a preset time of inactivity which may be minutes or hours) and may become invalid after a certain goal has been met (for example, once the buyer has finalized his order, he cannot use the same session ID to add more items).
As session IDs are often used to identify a user that has logged into a website, they can be used by an attacker to hijack the session and obtain potential privileges. A session ID is often a long randomly-generated string to decrease the probability of obtaining a valid one by means of a brute-force search. Many servers perform additional verification of the client, in case the attacker has obtained the session ID. Locking a session ID to the client's IP address is a simple and effective measure as long as the attacker cannot connect to the server from the same address.
A session token is a unique identifier, usually in the form of a hash generated by a hash function that is generated and sent from a server to a client to identify the current interaction session. The client usually stores and sends the token as an HTTP cookie and/or sends it as a parameter in GET or POST queries. The reason to use session tokens is that the client only has to handle the identifier (a small piece of data which is otherwise meaningless and thus presents no security risk) - all session data is stored on the server (usually in a database, to which the client does not have direct access) linked to that identifier. There are many drawbacks of session id and it's not enough to fulfill the developer requirements.[vague] Many developers use other logic to identify the session
1. Cookie机制
cookie机制是采用在客户端保持状态的方案.cookie的使用是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器检查所有存储的cookie,如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置,则把该cookie附在请求资源的HTTP请求头上发送给服务器。
cookie的内容主要包括:名字、值、过期时间、路径和域。路径与域一起构成cookie的作用范围。
若不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,关闭浏览器窗口,cookie就消失。这种生命期为浏览器会话期的cookie被称为会话cookie.会话cookie一般不存储在硬盘上而是保存在内存里.
若设置了过期时间,浏览器就会把cookie**保存在硬盘**上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过期时间。存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存里cookie,不同的浏览器有不同的处理方式。
2. Session 机制
session机制是一种服务器端的机制.
客户端对服务端请求时,服务端会检查请求中是否包含一个session标识( 称为session id ).
- 如果没有,那么服务端就生成一个随机的session以及和它匹配的session id,并将session id返回给客户端.
- 如果有,那么服务器就在存储中根据session id 查找到对应的session.
当浏览器禁止Cookie时,可以有两种方法继续传送session id到服务端:
第一种:URL重写(常用),就是把session id直接附加在URL路径的后面。
第二种:表单隐藏字段,将sid写在隐藏的表单中。
3. Token机制
Token是用户的验证方式,最简单的token组成:uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,由token的前几位+盐以哈希算法压缩成一定长的十六进制字符串,可以防止恶意第三方拼接token请求服务器)。
使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的: 1. 客户端使用用户名跟密码请求登录 2. 服务端收到请求,去验证用户名与密码 3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端 4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里 5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token 6. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
二、cookie与session的区别
1、cookie数据存放在客户端上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE
三、session与token的区别
作为身份认证 token安全性比session好,因为每个请求都有签名还能防止监听以及重放攻击
Session 是一种HTTP存储机制,目的是为无状态的HTTP提供的持久机制。Session 认证只是简单的把User 信息存储到Session 里,因为SID 的不可预测性,暂且认为是安全的。这是一种认证手段。 但是如果有了某个User的SID,就相当于拥有该User的全部权利.SID不应该共享给其他网站或第三方.
Token,如果指的是OAuth Token 或类似的机制的话,提供的是 认证 和 授权 ,认证是针对用户,授权是针对App。其目的是让 某App有权利访问 某用户 的信息。这里的 Token是唯一的。不可以转移到其它 App上,也不可以转到其它 用户 上。
四、会话管理机制中的漏洞
会话管理机制中存在的漏洞主要有两类: 1. 会话令牌生成过程中的薄弱环节 2. 在整个生命周期过程中处理会话令牌的薄弱环节
五、生成过程的薄弱环节
1. 令牌有一定含义
一些会话令牌通过用户名或者邮箱直接转换而来,或者使用一些基本的信息进行创建.这样就很比较容易构建令牌.
常见的具有含义的令牌有以下信息: 账户用户名 应用程序用来区分账户的数字标识符 用户的姓/名 电子邮件 日期/时间戳 一个递增/递减的数字 客户端的IP地址
令牌也很有可能会经过XOR,Base64,转化ASCII等方式先进行编码的操作,再进而生成令牌.
2. 令牌可预测
令牌可预测,主要是有这三个方面造成:隐含序列,时间依赖,生成的数字随机性不强.
隐含序列:主要是指令牌是通过简单的排列,然后进行编码或者进行十六进制的加减法操作而得到,只要猜测出它的基本方法,就可以进行发现规律.
时间依赖:令牌只根据时间的变换,使得令牌产生不同的伪随机.
随机性不强:指令牌是通过简单的线性同余函数生成,如果正好该函数又是公开的,比如java的java.util.Random函数等.
六、生命过程中的薄弱环节
1. 在网络上泄露令牌
当网站等以非机密的方式传送会话令牌时,就很有可能会导致令牌被窃听.比如使用非加密的HTTP的方式进行通信.
需要注意的是,有些网站虽然部分页面使用了HTTPS,但是还有部分页面使用HTTP,那么令牌就很有可能会在这些HTTP通信的页面中泄露.
2. 在日志中泄露令牌
主要原因可以是应用程序使用URL查询字符串,而不是使用HTTPCookie或者POST请求作为令牌的传输机制. 比如java web中,会在URL中后面带有 http://xxx.com;jsessionid=xxx ;当这样的URL写进日志或者其他历史记录中,那么sid就很容易被获取.
当Cookie被禁止后,就很容易出现使用URL进行传输令牌.
3. 会话终止易受攻击
有些站点,在用户退出后,它只通过set-Cookie等命令清除客户端的令牌,而服务端的令牌没有被删除.也可能会出现用户退出时,应用程序不与服务器通信,导致服务器什么操作都不做. 这些行为会导致当用户再次提交该令牌时,还能够与服务器通信.
4. 客户端暴露在令牌劫持的风险之中
攻击者可能通过XSS攻击用户,获取到用户的Cookie,获取令牌. 所以cookie中要注意设置HTTPOnly,这样可以减缓XSS攻击.