HTTP会话(未完成)

HTTP会话

第一节 概述

1.1 为什么需要会话?

服务器接收请求时需要标识用户身份,当然首先可以想到IP地址可以作为唯一标识符,即某个时间段内来自同一IP地址的所有请求一定属于相同客户端。但是网络地址转换(NAT)并不可靠,比如大学校园或大型企业,可能有数千人使用相同的IP地址,其真实IP则隐藏在NAT路由之后。我们需要一个维护用户状态的机制,而HTTP协议本身是无状态的,所以所有的HTTP服务器都普遍采用了HTTP会话的概念。

1.2 什么是会话?

在网络领域,会话(session)是一种持久网络协议,在用户端(或用户代理)和服务器端间创建关联,从而起到交换数据包的作用机制。在不包含会话层(UDP)或无法长时间驻留会话层(HTTP)的传输协议中,会话的维持需要依靠在传输数据中的高级版程序。例如HTTP中使用Cookie存放一些如 Session ID 、参数和权限信息等。

会话是由服务器或Web应用程序管理的某些文件、内存片段、对象或容器,它包含了应用分配给它的各种数据。容器和用户浏览器直接通过某种方式连接起来,通常是赋予一个随机生成的字符串 Session ID 也叫会话ID。

1.3 会话的作用

1.3.1 维持状态

会话用于维持请求和请求之间的状态,HTTP请求自身是完全无状态的。在无状态的方式下,大部分应用程序无法正常工作,比如购物网站,所有的行为和功能都要基于用户身份,如购物车、收藏夹、支付等,可以想象没有状态的话所有的功能都必须一次成功走完,会话是维持请求状态的引擎。

1.3.2 记住用户

会话的机制让系统能够记住用户:如论坛等网站,用户都要有用户名或“匿名”,用户登录后可以添加主题、回复主题、参与此人讨论等,所有流程中用户只须登录一次,系统需要记住此用户。

1.3.3 启动应用程序工作流

通常用户在使用一些高级功能时,需要使用某种形式的工作流,比如新闻网站中发布新闻时,首先要进入编写标题、标语和正文的页面,然后下个页面选择相关图片,最后还可能要选择一些类似文章或关键字。以上三个步骤完成后,新闻被发布出去,这样的工作流通常包含多个步骤,每个步骤是单个任务,共同构成了整个工作流,所以请求之间需要维持一个状态。


第二节 简单使用

2.1 Cookie、Session、Token

相关内容:Cookie,Session,Token

2.2 传输会话ID

有两种流行的方式来传输会话ID:

  • 通过Set-Cookie头将JSESSIONID发送给浏览器。
  • 通过URL直接拼接JSESSIONID。

第二种方式可以避免使用Cookie,但所有请求URL都会嵌入会话ID。

2.3 会话常见漏洞

可以通过一些漏洞检测工具或如Open Web Application Security Project(OWASP)网站来进行检查。

2.3.1 复制并粘贴错误

使用URL拼接的方式传输SessionID会面临一个问题:用户可能会不小心把URL复制到互联网上,如果一些人在会话结束前访问此URL,那么自然也会变当作此用户。

解决此问题的方法就是不要使用URL拼接这种方式,这并不奇怪,大部分网站都采用Cookie来作为通用的解决方案。

2.3.2 会话固定

会话固定攻击类似于复制粘贴错误,攻击者首先获得一个拼接SessionID的URL,然后将此URL传播出去,不知情的用户通过此URL在会话期间登录网站,那么攻击者也能够登录成功并访问被攻击用户的账户。

解决方法有:

  • 禁止在URL中嵌入会话ID,同时也需要在应用程序中禁止接受通过URL传递的会话ID。
  • 在登录后采用会话迁移。即用户登录后,修改会话ID并将之前会话ID无效。

2.3.3 跨站脚本和会话劫持

跨站脚本攻击(CSRF):攻击者会通过将JS注入某个页面,通过DOM属性 document.cookie 读取会话Cookie的内容,攻击者获得会话ID后,可以通过创建Cookie/或URL嵌入来模拟会话,直接使用被攻击用户的身份。

大致的触发流程是:

  1. 用户登录了站点A,并且在Cookie中留下了A站点的认证信息
  2. 用户进入了站点B,而站点B用一些方式(比如一个提交行为是到A站点某关键接口的表单)引诱用户去点击。当用户点击时,会发出到A站点的请求。而浏览器会给这个请求附带上A站点的认证信息,从而让这个请求能够执行。这种行为可能是,但不限于,给某个A站点的某个其他用户提权/转账/发文辱骂等等。

解决方法:

  1. 编码和过滤,将HTML字符转换为 HTML Entities 编码,对js代码进行转义。
  2. 避免使用 Cookie ,而使用 Local Storage ,但会使XSS攻击更容易。
  3. 使用 CSRF Token 作表单验证。
  4. 给所有接口都添加一个请求 secret ,来标记其来自于合法的客户端。
  5. Same-Site Cookie 限制站点必须同域名才能携带cookie。
  6. 总是用 json 格式提交,禁止允许跨域的 application/x-www-form-urlencoded 格式,而使用application/json
  7. 双认证,认证信息同时存放在 HttpOnly CookieAuthorization Header ,并在服务器对比。
  8. 使用HTTPS,将Cookie设置为Secure,浏览器就可以只在访问https网址时才会携带Cookie。

2.3.4 不安全的Cookie

中间人攻击(MitM):是一种典型的数据截获攻击,攻击者通过观察客户端和服务端交互的请求或响应,从中获取信息。

这种类型的攻击促进了安全套接字层传输层安全(SSL/TLS)的发展,是HTTPS协议的基础。

解决方案是使用HTTPS协议,但仍存在的问题是应用可能同时支持HTTP和HTTPS,那么在HTTP请求重定向到HTTPS时攻击可能已经发生了(在用户浏览器通过未加密的方式发送会话ID cookie时,观察者已经窃取到此ID)。这种情况需要使用Cookie的 Secure 特性,此标志告诉浏览器只能通过HTTPS传输Cookie,即一直使用HTTPS

2.3.5 安全的会话

SSL/TLS 会话 ID 通过去除必须在每次请求中都执行SSL握手的需求,改善了SSL协议的效率。SSL/TLS 会话 ID 在SSL握手期间建立,然后使用在后续请求中,将请求绑定在一起,决定加密和界面所使用的密钥。它与 HTTP 会话 ID 的区别在于其并不通过URL或Cookie来传输或存储,而是需要认证授权才能获取。

使用 SSL/TLS 会话 ID 需要一直使用HTTPS协议,并且SSL通信必须由Web容器完成,如果使用了Web服务器或负载均衡器管理SSL通信,Web容器将无法获得通信中的 SSL/TLS 会话 ID 值。在集群环境中,用户的请求必须要一直发生到同一服务器(多机不会备份会话信息)。服务端存储 SSL/TLS 会话 ID 对应的信息不太容易控制失效时间,太短起不到作用,太长又占用服务端大量资源。


第三节 在会话中存储数据


第四节 使用会话


第五节 将使用会话的应用集群化


参考:

🔗 《JavaWeb高级编程——涵盖WebSockets、Spring Framework、JPA Hibernate和Spring Security》