diff --git a/build.gradle b/build.gradle index f8b099bb8..e9ceaa90c 100644 --- a/build.gradle +++ b/build.gradle @@ -137,7 +137,7 @@ dependencies { if (System.getenv("DOCKER_ENABLE_SECURITY") != "false") { implementation "org.springframework.boot:spring-boot-starter-security:$springBootVersion" - runtimeOnly "org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.2.RELEASE" + implementation "org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.2.RELEASE" implementation "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion" implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootVersion" @@ -154,6 +154,8 @@ dependencies { implementation "org.springframework.security:spring-security-saml2-service-provider" implementation 'com.coveo:saml-client:5.0.0' + + } testImplementation "org.springframework.boot:spring-boot-starter-test:$springBootVersion" diff --git a/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java b/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java index 04469cec8..618c39d6d 100644 --- a/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java +++ b/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java @@ -36,6 +36,8 @@ import org.springframework.security.saml2.provider.service.web.authentication.Sa import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; +import org.springframework.security.web.csrf.CookieCsrfTokenRepository; +import org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler; import org.springframework.security.web.savedrequest.NullRequestCache; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; @@ -94,6 +96,16 @@ public class SecurityConfiguration { userAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); if (applicationProperties.getSecurity().getCsrfDisabled()) { http.csrf(csrf -> csrf.disable()); + } else { + CookieCsrfTokenRepository cookieRepo = + CookieCsrfTokenRepository.withHttpOnlyFalse(); + CsrfTokenRequestAttributeHandler requestHandler = + new CsrfTokenRequestAttributeHandler(); + requestHandler.setCsrfRequestAttributeName(null); + http.csrf( + csrf -> + csrf.csrfTokenRepository(cookieRepo) + .csrfTokenRequestHandler(requestHandler)); } http.addFilterBefore(rateLimitingFilter(), UsernamePasswordAuthenticationFilter.class); http.addFilterAfter(firstLoginFilter, UsernamePasswordAuthenticationFilter.class); @@ -113,6 +125,7 @@ public class SecurityConfiguration { logout.logoutRequestMatcher(new AntPathRequestMatcher("/logout")) .logoutSuccessHandler( new CustomLogoutSuccessHandler(applicationProperties)) + .clearAuthentication(true) .invalidateHttpSession(true) // Invalidate session .deleteCookies("JSESSIONID", "remember-me")); http.rememberMe( @@ -223,6 +236,16 @@ public class SecurityConfiguration { } else { if (applicationProperties.getSecurity().getCsrfDisabled()) { http.csrf(csrf -> csrf.disable()); + } else { + CookieCsrfTokenRepository cookieRepo = + CookieCsrfTokenRepository.withHttpOnlyFalse(); + CsrfTokenRequestAttributeHandler requestHandler = + new CsrfTokenRequestAttributeHandler(); + requestHandler.setCsrfRequestAttributeName(null); + http.csrf( + csrf -> + csrf.csrfTokenRepository(cookieRepo) + .csrfTokenRequestHandler(requestHandler)); } http.authorizeHttpRequests(authz -> authz.anyRequest().permitAll()); } diff --git a/src/main/resources/templates/change-creds.html b/src/main/resources/templates/change-creds.html index 8dfdeaeb9..0ba3ed7b2 100644 --- a/src/main/resources/templates/change-creds.html +++ b/src/main/resources/templates/change-creds.html @@ -27,7 +27,7 @@