HTTP协议是无状态的,这就意味着Web应用并不了解有关同一个用户以前请求的信息。会话是在服务器端维护每次HTTP请求的状态,使用会话标识符的最常见原因是允许用户只进行一次验证,而不是在与应用程序的一系列交互中携带认证信息。会话标识符就基本等同于用户名/密码、一次性令牌等,每个用户的会话标识符都应该是唯一的以及不可预测的。可以将会话标识符作为URL参数来回传送,但是现在大多数应用程序都使用cookies来处理它们。
名词解释
会话ID(SID):由服务器产生并返回给浏览器的请求,并且在浏览器中存储(通常来说是Cookie),它用来标识浏览器与服务器会话的唯一值。
Cookie:指浏览器客户端用来存储SID的内存或者文件。
会话内存分配:在服务器端存储来自浏览器请求的一些特殊值,如用户名等信息,它和SID是相关联的。
会话产生过程
1)用户通过浏览器访问一个应用服务器,起始的时候用户发给服务器的请求并没有任何会话ID;
2)当服务器收到用户发过来的请求时发现,该请求没有会话ID,于是它会产生一个新的唯一会话ID,并且在服务器端分配内存,返回给浏览器,同时在应答中通过set-cookie在HTTP header中设置该会话ID;
3)浏览器收到了含有被设置Cookie的应答,于是它将定义在HTTP header中的会话ID保存在Cookie中;
4)此后,每次浏览器向该服务器发送请求时,都会在请求的HTTP header中附上“cookie:”;
5)服务器收到来自浏览器的请求,如果该请求含有合法的会话ID,它就会在会话内存中寻找与此会话ID对应的对象/值。
如何保护会话安全
1)使用新的会话
当用户认证时,永远要生成一个新的会话,即使已经有一个会话ID与该用户进行了关联。
如果应用程序没有为无论何时认证的用户生成一个新的会话,那么就存在会话固定攻击的潜在风险,攻击者能够将一个已知会话ID强加给一个用户。
2)使用强用户会话标识符
会话ID必须具有随机性和不可预测性。一般来说,会话ID的长度至少为128位。较短的会话ID会使应用程序容易受到强力会话猜测攻击,假如攻击者能够猜到一个认证用户的会话标识符,他们就可以接管该用户的会话。
3)会话空闲超时
会话一般都有有效期,通常是30分钟。会话过期以后,服务器会擦除相应的分配内存。
通常有3种办法来设定会话过期,其级别由高到低依次为:Tomcat级别〉Web应用级别〉Servlet运行时context级别,低级别的设定会覆盖高级别的设定。
a) Tomcat级别的设定
在{TOMCAT_HOME}\conf\web.xml中进行如下设定:
<session-config>
<session-timeout>30</session-timeout>
</session-config>
b) Web应用级别的设定
在{TOMCAT_HOME}\webapps\{APP_NAME}\WEB-INF\web.xml中进行如下设定:
<session-config>
<session-timeout>15</session-timeout>
</session-config>
c) 在程序代码中进行设定
httpSession.setMaxInactiveInterval(5*60);
4)最大会话持续时间
设定一个会话过期时间,当超过这段时间后系统会强制用户重新进行认证。Servlet规范没有强制一种机制用于设置最大会话持续时间,可以通过在web filter中写自己的代码来实现此功能。如下面这段代码:
Public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)
throws IOException, ServletException{
if(request instanceof HttpServletRequest){
HttpServletRequest hres = (HttpServletRequest)request;
HttpSession sess = hres.getSession(false);
if(sess!=null){
long now = System.currentTimeMillis();
long then = sess.getCreationTime();
if((now-then) > MAX_SESSION_LIFETIME) {
sess.invalidate();
}
}
}
chain.doFilter(request,response);
}
5)保护你的Cookie
Cookie有两个很重要的属性:secure和HttpOnly,设置好这两个属性对于保护你的Cookie至关重要。
Secure属性,声明了它代表当前这个Cookie只会在HTTPS的链接中进行传递,这样就可以使得攻击者无法很容易地通过分析网络流量来获得会话ID,从而有效地防范了中间人攻击。
HttpOnly属性,它不运行一些脚本(如JavaScript等)直接操作document.cookie这个DOM对象,这个属性对于阻止通过XSS窃取会话ID是必需的。
6)确保用户能够退出
网页中要包括一个退出链接,它允许用户中断他们的HTTP会话。允许用户中断自己的会话能够从下列各方面保护用户和系统:
a) 一个在公共终端上的用户没有其他方法来防止下一个人在该终端上访问他的账号。
b) 通过中断会话,用户可以保护他的账号。
c) 通过清除不再使用的会话,服务器可以减少攻击者可用于猜测的平均有效会话数量。