安全技术研究-Broken Session Management(JAVA代码)

漏洞代码示例(JAVA servlets)

认证成功后,当前会话不会失效:

public void doAction(HttpServletRequest request, HttpServletResponse response) {
    String pwd = request.getParameter("j_password");
    String usr = request.getParameter("j_username");
    SessionUser user = persistenceController.loginUser(usr, pwd);
    String msg = "";
    try {
        if (user != null) {

            // XXX session not invalidated!

            request.getSession().setAttribute(Constants.USER, user);
            msg = messageGenerator.RedirectMessage("/ok.html");
        } else {
            msg = messageGenerator.redirectMessage("/error.html");
        }

        PrintWriter out;
        out = response.getWriter();
        out.print(msg);
        out.flush();
    } catch (IOException e) {
        // ...
    }
}

解决方案是使当前会话无效,然后为新登录的用户创建一个新的会话:

request.getSession().invalidate();
request.getSession(true);

另一个漏洞代码示例


在本例中,注销时会话不会失效。cookie的值只在用户的浏览器中被清除:

@Override
public void doAction(HttpServletRequest request, HttpServletResponse response) {
    Cookie cookie = new Cookie("JSESSIONID","LOGOFF");
    response.addCookie(cookie);

    // XXX session not invalidated!

    response.sendRedirect("/");
}

解决方案是使会话失效:

request.getSession().invalidate();

如何防护

对于会话固定的问题,在用户身份验证成功后调用HttpSession类的invalidate方法。然后通过将true传递给HttpServletRequest类的getSession方法来创建一个新的会话。

第三方框架可能已经集成了处理会话管理的解决方案;一定要通过阅读第三方框架的帮助文档了解如何使会话失效。

确保在注销时通过调用HttpSession类的invalidate方法使会话失效。