【问题标题】:Session ID re-used after call to invalidate调用无效后重用会话 ID
【发布时间】:2011-10-13 01:48:20
【问题描述】:

我继承了一个非常古老的 JSP 应用程序 (JDK 1.3.1_15),并试图填补会话固定漏洞。

在使用HttpSession.invalidate() 进行身份验证后,我成功地使当前会话无效,但是在创建新会话时,旧的会话 ID 被重新使用。

<%
// login.jsp
if (authenticated) {
    request.getSession().invalidate();

    // create new session and store data
    HttpSession session = request.getSession();
    session.putValue(...);
    // etc

    response.sendRedirect("logged-in.jsp");
    return;
}
%>

我可以在我的 HTTP 监视器中看到新的会话分配,它只是再次使用相同的数字。

-- Initial request response --
HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=6a303082951311647336934;path=/

-- login.jsp request response --
HTTP/1.1 302 Moved Temporarily
Location: http://example.com/logged-in.jsp
Set-Cookie: JSESSIONID=6a303082951311647336934;path=/

在我使用session.invalidate() 之前,第二个Set-Cookie 响应标头根本不存在。

有人对如何生成新的会话 ID 有任何建议吗?我对 JRUN4 不是很熟悉,但是翻阅配置文档并没有发现任何东西。

【问题讨论】:

  • 是否有可能在调用session.invalidate() 之前将某些内容写入输出流?例如,scriptlet(&lt;%%&gt;)标签之外的任何内容?
  • @mattb 不,已经解决了这个问题。新会话肯定是在调用 invalidate() 之后创建的
  • 我只是扔掉“JRUN”(或任何它假装的东西,我不希望在这里得到太多社区支持)并使用一个真实而体面的 servlet 容器。 Tomcat 和 Jetty 是不错的轻量级替代品。试一试。说服你的经理。我知道这在技术上并不能回答你的问题,但它也只是一个评论:) 祝你好运。
  • @BalusC 不幸的是,这不是一个选项

标签: java jsp httpsession jrun


【解决方案1】:

要解决此问题,您可以使用第二个非持久性 cookie 作为您可以控制其值的会话 ID。这个想法是生成一个唯一的 id 并将其存储在 cookie 和会话中。使用此 cookie 实现与您尝试通过使用 invalidate 对会话执行相同的逻辑。具体来说,在身份验证成功之前,不要发出将被未来请求接受的实际标识符。然后创建一个 Servlet 过滤器,它检查每个请求并将这个新 cookie 的值与会话中存储的值相匹配。如果它们不匹配,就会发生一些邪恶的事情。我知道这比仅仅依靠session.invalidate() 发出一个新的id 要麻烦一些。但是考虑到您的限制和 JRun 的行为,这将提供足够的保护来防止会话固定。

【讨论】:

  • 如果客户端禁用了 cookie 怎么办?
  • 那么您需要采用相同的方法将 id 附加到 JSESSIONID 禁用 cookie 时出现的 URL。 HttpServletRequest.isRequestedSessionIdFromURL() 方法可用于确定会话是通过 cookie 管理还是通过附加来管理。然后,您需要创建一个实用程序来将辅助会话 ID 附加到 URL。您还需要一个 Servlet 过滤器,如下所述:stackoverflow.com/questions/962729/…,除非您还需要返回带有辅助会话 ID 的 URL。
  • 如果我们必须自己实现会话处理等基本功能,这是一个相当低级的容器。
【解决方案2】:

Java Servlet 3.0 specification的第7.3节可以看到:

HttpSession 对象必须在应用程序(或 servlet 上下文)级别。 底层机制,例如用于 建立会话,对于不同的上下文可以是相同的,但是 引用的对象,包括该对象中的属性,绝不能 由容器在上下文之间共享。

这是一个非常糟糕的想法,但我想知道 JSESSIONID cookie 是否只是简单地重复使用而实际的会话上下文被破坏了。你还能访问无效会话的状态(即属性)吗?

【讨论】:

  • 不,所有会话对象都不受invalidate() 调用的约束。似乎大多数其他容器将为新会话分配一个新 ID,而不是 JRun
  • @Phil:当然,因为分配一个新的 ID 是最有意义的。但是,如果 JRun 按字面意思解释规范,似乎没有特别需要这样做。
  • @Phil:我刚刚尝试过 Tomcat 7.0.12 和 WebSphere 7.0。他们立即分配一个新的 JSESSIONID - 玩 JRun :-)
  • @hoipolloi:我不同意,这是一个安全问题。登录后,您可以切换到 HTTPS,因此您需要一个新 ID,至少在旧 ID 被不安全地传输的情况下。
  • @home:它在规范中的什么地方说明了这一点?不要误会我的意思,我不是在为这个实现辩护;只是试图理解为什么 JRun 会做这种违反直觉的事情。
猜你喜欢
  • 1970-01-01
  • 2019-08-13
  • 1970-01-01
  • 2019-09-26
  • 1970-01-01
  • 1970-01-01
  • 2015-08-14
  • 2017-08-06
  • 2021-04-09
相关资源
最近更新 更多