【发布时间】:2011-01-19 15:58:16
【问题描述】:
我正在维护一个 Java Web 应用程序。
查看登录代码,它通过 HttpServletRequest 的 getSession() 方法从 HttpServletRequest 中获取 HttpSession。 (它使用会话中的一些值进行身份验证)
但是我担心会话固定攻击,所以在使用初始会话后,我想启动一个新会话或更改会话 ID。这可能吗?
【问题讨论】:
我正在维护一个 Java Web 应用程序。
查看登录代码,它通过 HttpServletRequest 的 getSession() 方法从 HttpServletRequest 中获取 HttpSession。 (它使用会话中的一些值进行身份验证)
但是我担心会话固定攻击,所以在使用初始会话后,我想启动一个新会话或更改会话 ID。这可能吗?
【问题讨论】:
Servlet 3.0 API 不允许您更改现有会话的会话 ID。通常,为了防止会话固定,您只需创建一个新的并使旧的无效。
您可以像这样使会话无效
request.getSession(false).invalidate();
然后用
创建一个新会话getSession(true)(getSession() 也应该可以)
显然,如果您想要持久化会话中的数据,则需要将其从第一个会话复制到第二个会话。
注意,对于会话固定保护,通常认为只对身份验证请求执行此操作是可以的。但是更高级别的安全性涉及丢弃旧会话并为每个请求创建一个新会话。
【讨论】:
getSession() 而不是 getSession(boolean),我会支持您。
request.getSession(false).invalidate(); 带有空检查是正确答案。
从 Java EE 7 和 Servlet API 3.1 (Tomcat 8) 开始,您可以使用 HttpServletRequest.changeSessionId() 来实现这种行为。还有一个监听器HttpSessionIdListener,每次更改后都会调用它。
【讨论】: