在我们的 Spring Security 课程的这篇文章中,我们将研究Spring Security 会话固定以及如何防止我们的 Spring 应用程序中的会话劫持。
会话固定是一种非常常见且最常见的攻击类型,恶意攻击者可以通过访问站点来创建会话,然后说服另一个用户使用相同的会话登录(通过向他们发送包含会话的链接标识符作为参数,例如)。将会话固定视为一种漏洞,攻击者将诱骗您登录应用程序,然后使用您的会话访问同一站点。请记住以下要点,以便更好地理解。
在我们详细了解Spring 安全会话修复以及安全性如何帮助我们解决这个潜在问题之前,我们必须清楚地了解这个问题。会话固定是一种攻击,可以通过多种方式完成。以下是高级攻击的样子:
如果用户没有登录,这不是问题,但是如果应用程序在用户通过身份验证后继续使用相同的会话 id,就会变得很严重。请记住,Spring 安全身份验证依赖于会话 ID 来检查会话是否经过身份验证。使用相同的会话 id,恶意攻击者可以使用相同的会话 id 进行身份验证,无需用户名或密码。这种攻击有多种变体,让我们检查其中的几个:
1.1 随机 SID
有许多应用程序不仅可以接受会话 ID,还可以接受客户端提供的任何其他 ID。如果是这种情况,攻击者很容易生成一个随机 ID 并将其与登录请求一起传递。
1.2 服务器会话 ID
如果应用程序只允许应用程序生成的会话 id,它会增加一个步骤,让攻击者先从应用程序获取有效的会话 id,然后才能欺骗受害者使用他们的会话 id 进行登录。在这种方法中,攻击者几乎没有额外的挑战。
获得会话后,他们可以将客户重定向到带有会话 ID 的登录页面:https://www.javadevjournal.com/login?SID=987654321。这只是一个示例,但请记住,在典型的基于 Java 的 Web 应用程序中,您可以使用以下选项传递会话 ID:
URLCookiesSSL这是一个高级工作流程,可让您更清楚地了解会话固定攻击的工作原理

默认情况下,Spring security 通过在 用户登录时创建新会话或以其他方式更改会话 ID 来保护会话固定攻击。spring security session fixation确保攻击者无法使用旧会话访问应用程序。sessionManagement您可以使用以下配置控制 spring 安全会话固定策略
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- http.authorizeRequests()
- ...
- sessionManagement()
- .sessionFixation().none();
- }
Spring Security 为会话管理和会话固定提供了不同的选项,您可以随时根据需要更改或调整它。
| 会话固定策略 | 描述 |
none() | Spring security 将禁用会话固定保护。 |
migrateSession() | 当用户成功通过身份验证时,将创建一个新会话并将旧会话值移动到新会话。(默认并适用于大多数情况) |
newSession() | 当用户成功通过身份验证时,将创建一个新会话,并且不会从旧会话复制任何属性。 |
changeSessionId() | 这是使用新的 Servlet 容器(Servlet 3.1 和更新版本)完成的。用户认证后不会创建新会话,但会更改会话 ID。 |
当会话固定保护发生时,它会导致在SessionFixationProtectionEvent应用程序上下文中发布
我们知道默认情况下 Spring Security 提供会话固定保护,我们也可以根据需要对其进行自定义。同样重要的是,我们了解这种保护如何在内部与 Spring 安全性一起工作。Spring security 使用以下类来处理这个问题。
SessionManagementFilter.SessionAuthenticationStrategy3.1 会话管理过滤器
检查用户是否是新认证的SessionManagementFilter,如果它是认证的,它会将工作交给SessionAuthenticationStrategy来决定如何处理会话(例如应该迁移或创建新会话。我们可以通过 来控制SessionManagement)。这是SessionManagementFilter过滤器的代码片段:
- if (!securityContextRepository.containsContext(request)) {
- Authentication authentication = SecurityContextHolder.getContext()
- .getAuthentication();
-
- if (authentication != null && !trustResolver.isAnonymous(authentication)) {
- // The user has been authenticated during the current request, so call the
- // session strategy
- try {
- sessionAuthenticationStrategy.onAuthentication(authentication,
- request, response);
- }
-
- // other code
- }
- }
SecurityContextRepository以确定用户是否已通过身份验证。newSession或migrateSession等等)。InvalidSessionStrategy.3.2 会话认证策略
这是一个接口,用于确定用户通过身份验证后应使用哪个 spring 安全会话固定策略。带有弹簧安全性的 OOTB 有不同的可用策略,它们将根据配置触发。例如,SessionFixationProtectionStrategy将处理以下两个用例。
migrateSession()并复制现有会话的所有属性。newSession(),他们不会从旧会话中复制任何属性。使用此功能时,请注意以下可能导致某些问题且难以调试的潜在问题:
HttpSessionBindingListener在自定义对象中使用并使用它,则复制会话属性可能会导致一些问题。DisposableBean假设不再需要 bean,从 session 中删除 bean 将导致调用接口。
在本文中,我们讨论了Spring Security 会话固定保护。本文的源代码作为 Spring 安全教程的一部分在GitHub 上提供。总而言之,我们了解到: