如果我们按照上面的步骤进行了会话过期设置,那么最后真正起作用的是在程序中进行设定的5分钟。
再看什么是硬会话过期。它指的是用户登录到系统中经过一定的时间后,不管用户做什么,该会话都会过期。大家都知道网络游戏防沉迷系统吧?如果未成年人的累计在线时间已满5小时,则累计在线时间清零,这个与我们这里说的硬会话过期很相似,只不过我们这里不是在线时间清零,而是强制用户退出并重新登录。
那么硬会话过期有什么用呢?它主要是用来防止永久的对一个账号劫持。比如说一个攻击者通过XSS得到了受害者的session,并用它冒充受害者进行登录,如果我们设定了硬会话过期,则经过了一段时间之后,系统会强制用户重新进行认证。
没有专门的API或者配置来设定硬会话过期,但我们可以通过在web filter中写自己的代码来实现这个功能。基本思路如下:对每个用户登录成功后记录下此时的时间,并且把这个时间与他们的Session ID绑定起来,如果用同一个Session ID发送的请求的时间减去这个Session ID刚登录成功的时间大于了我们设定的会话过期时间,则使这个会话无效,并重定向到登录页面。
3.保护你的Cookie
Cookie有两个很重要的属性:secure和HttpOnly,设置好这两个属性对于保护你的Cookie至关重要。
首先说secure属性。声明了它,则说明当前这个Cookie只会在HTTPS的链接中进行传递,这样就可以使得攻击者无法很容易地通过分析网络流量来获得会话ID,从而有效地防治了中间人攻击(Man-in-the-Middle)。
HttpOnly这个属性我们在XSS这一章已经介绍过,它不允许一些脚本(如JavaScript等)直接操作document.cookie这个DOM对象,这个属性对于阻止通过XSS窃取会话ID是必需的。
一个好消息是,Tomcat 7支持了Servlet 3.0,所以我们可以在web.xml设定上面的两个属性。
- <session-config>
- <cookie-config>
- <secure>true</secure>
- </cookie-config>
- <cookie-config>
- <http-only>true</http-only>
- </cookie-config>
- </session-config>
需要注意的是Tomcat 6以前的版本不支持,Tomcat 6支持的是Servlet 2.5。
4.提供logout功能
上面介绍的是系统自动按照设定的时间使会话过期,一个好的应用程序应该提供一个功能,即用户可以手动地使当前会话过期,这就是我们在几乎所有网站上都看到的logout按钮。那么一般的logout需要完成哪些功能呢?让我们看看ESAPI中是如何实现logout功能的吧。
- Class: org.owasp.esapi.reference.DefaultUser
- public void logout() {
- ESAPI.httpUtilities().killCookie( ESAPI.currentRequest(),
- ESAPI.currentResponse(),
- HTTPUtilities.REMEMBER_TOKEN_COOKIE_NAME );➊
- HttpSession session = ESAPI.currentRequest().getSession(false);
- if (session != null) {
- removeSession(session);
- session.invalidate();➋
- }
- ESAPI.httpUtilities().killCookie(ESAPI.currentRequest(),
- ESAPI.currentResponse(),
- "JSESSIONID");➌
- loggedIn = false;
- logger.info(Logger.SECURITY_SUCCESS, "Logout successful" );
- ESAPI.authenticator().setCurrentUser(User.ANONYMOUS);
- }
killCookie的实现代码如下:
- public void killCookie(HttpServletRequest request, HttpServletResponse response, String name) {
- String path = "//";
- String domain="";
- Cookie cookie = getFirstCookie(request, name);
- if ( cookie != null ) {
- path = cookie.getPath();
- domain = cookie.getDomain();
- }
- Cookie deleter = new Cookie( name, "deleted" );
- deleter.setMaxAge( 0 );➍
- if ( domain != null ) deleter.setDomain( domain );
- if ( path != null ) deleter.setPath( path );
- response.addCookie( deleter );
- }
我们简单地分析一下上面的代码:
的作用是清除remember me这个Cookie,这是针对网站有remember这个功能来说的。
是使得当前的会话无效,这样即使当前的会话ID泄露出去了,攻击者也无法用这个会话ID进行登录。
的作用是清除JSESSIONID这个Cookie。
使deleter(与传递进来的Cookie同名)立即无效。



