HttpSession 机制及安全防范

一,什么是Http Session

由于http 协议是无状态的,我不能知道当前的request来至于哪一个特定的用户。为来解决这个问题,需要request中携带特定的参数,表明用户身份,而Server端基于这个参数来维护一份该用户特有的上下文会话,称之为session。这个特定参数叫做Session id。

二,基于Session的会话机制

1,client 发起一个request到server端
2,server端基于该request,生成一份session,同时将该session id传递给client端
3,client收到response后,存储session id在本地,一般使用cookie存储。
4,client以后的每份请求都携带该sesion id
5,server端收到request后,通过其中的session id,识别特定用户发来的request,从而认证成功,并可取该session id对应的session中的数据

以上保证了有状态的会话得意实现

三,如何实现分布式Session

在java中session 一般有web 容器生成和管理,不能被多个web 容器共享。在分布式系统并行的今天,一个用户访问的站点www.example.com 可能对用多个web 容器实例。如何才能实现分布式Session?解决的思想主要有两个:

1,通过一定机制,保证单个用户始终路由到同一个web 容器上

2,在不同的web 容器间实现session 同步。实现该种方式的机制可能如下:

  • 通过web 容器自身的机制,貌似tomcat有类似的
  • 将session持久化到数据库。不同web 容器在收到client 请求时,去数据库读取用户session。当然如果数据量大的话,可能数据库层面也要做分布式处理。
  • 使用redis或memcache等分布式缓存来存储session

四,安全防范

1,session id应始终存放在cookie中,而不是post或url参数

cookie具有更丰富的安全控制,比如到期时间设置,并且不容易泄漏,和招致fixation attacks

2,来之每个请求的session id都应该被验证

避免黑客伪造的非法session id导致的sql 注入(若session 存在数据库中)。或xss攻击。每次请求的session id都应该被验证

3,session id的cookie属性应该被设置为secure和http only

xss攻击时,黑客可通过xss注入脚本代码获取用户的cookie,从而获取用户的sessionid。为防止此种攻击,应该将cookie 的属性设置为http only,这样js将不能读取cookie。java 的cookie api中没有http only属性,可通过server 容器进行配置来实现。

数据传输时,黑客可能拦截请求,从而获取通信内容,比如session id。为了防范此种攻击,可以设置某cookie使用安全通道传入(https)。在java中是Cookie.setSecure(boolean flag)来实现。

4,权限变更时,应废弃老的session ID,重新生成session id

如果不在权限变更时(比如用户从未登录态变成登录态,或从普通权限变成管理员权限)更新session id,那么很容易招致fixation attacks。攻击理论大概是黑客发给一个带session id(未登录时的sesion id)诱惑用户登录,登录后该session id在server端认证通过,打开了权限。黑客便可通过该session id一样获取了用户的授权访问内容。具体解释见危机百科的fixation attack. java 中重新生成session id的方式为:request.getSession(true) & HttpSession.invalidate()