Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

samesite set by Tomcat CookieProcessor ignored when creating XSRF-TOKEN cookie in CsrfTokenRepository #14131

Closed
burghduffkc opened this issue Nov 12, 2023 · 9 comments
Assignees
Labels
in: web An issue in web modules (web, webmvc) type: bug A general bug
Milestone

Comments

@burghduffkc
Copy link

burghduffkc commented Nov 12, 2023

Describe the bug
Prior to Spring Security 6, the CsrfTokenRepository used the response.addCookie in the saveToken method to add the XSRF-TOKEN cookie. In Spring-Security 6 it was changed to call response.addHeader which bypasses the Tomcat CookieProcessor.

To Reproduce
I forked the Spring-Security-Samples project and used hello-security-explicit
https://github.com/burghduffkc/spring-security-samples/commits/main/servlet/spring-boot/java/hello-security-explicit, below are the modifications and steps to reproduce.

  1. Add the following to the HttpSecurity in the SecurityFilterChain bean of the SecurityConfiguration class
.csrf((httpSecurityCsrfConfigurer -> {
			 //START Bug change
	httpSecurityCsrfConfigurer
		.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
		.ignoringRequestMatchers(request -> Pattern.compile("^(GET)$").matcher(request.getMethod()).matches());
}))
  1. Add the following Bean to the SecurityConfiguration class
	@Bean
	WebServerFactoryCustomizer<TomcatServletWebServerFactory> servletWebServerFactoryWebServerFactoryCustomizer(){
		return container -> container.addContextCustomizers(context -> {
			Rfc6265CookieProcessor rfc = new Rfc6265CookieProcessor();
			rfc.setSameSiteCookies("STRICT");
			context.setCookieProcessor(rfc);
		});
	}
  1. run the spring boot application
  2. Open Chrome and the Chrome Developer tools and access http://locahost:8080
  3. Look at the cookies under Application -> Storage -> Cookies. You will see that the JSESSIONID cookie has the sameSite set to Strict, but the XSRF-TOKEN does not have sameSite set. This is because the CsrfTokenRepository#saveToken does not use addCookie, bypassing the Tomcat CookieProcessor.

Expected behavior
A clear and concise description of what you expected to happen.
The XSRF-TOKEN cookie should have sameSite set to Strict.
Sample

Change to hello-security-explicit sample
burghduffkc/spring-security-samples@fb8971a

Full code for Spring-Security Example
https://github.com/burghduffkc/spring-security-samples/commits/main/servlet/spring-boot/java/hello-security-explicit

A link to a GitHub repository with a minimal, reproducible sample.

Reports that include a sample will take priority over reports that do not.
At times, we may require a sample, so it is good to try and include a sample up front.

@burghduffkc burghduffkc added status: waiting-for-triage An issue we've not yet triaged type: bug A general bug labels Nov 12, 2023
@marcusdacoregio marcusdacoregio self-assigned this Nov 13, 2023
@marcusdacoregio marcusdacoregio added in: web An issue in web modules (web, webmvc) and removed status: waiting-for-triage An issue we've not yet triaged labels Nov 13, 2023
@marcusdacoregio
Copy link
Contributor

marcusdacoregio commented Nov 13, 2023

Hi, @burghduffkc. Thanks for the report.
I've successfully reproduced the error on my side. We are working on a fix.

@marcusdacoregio marcusdacoregio added this to the 6.1.6 milestone Nov 13, 2023
@marcusdacoregio
Copy link
Contributor

For the time being, you can work around that by customizing the cookie generated by the CookieCsrfTokenRepository, like so:

var repository = CookieCsrfTokenRepository.withHttpOnlyFalse();
repository.setCookieCustomizer((customizer) -> {
	customizer.sameSite(sameSitePolicy);
});

@burghduffkc
Copy link
Author

@marcusdacoregio Thank you for the suggestion, unfortunately that would require us to update all applications, as our current Tomcat CookieProcessor is configured in the context.xml file and not in Spring.

Example Configuration for context.xml
<Context> <CookieProcessor className="org.apache.tomcat.util.http.Rfc265CookieProcessor" sameSiteCookes="strict" /> </Context>

@marcusdacoregio
Copy link
Contributor

Thanks, @burghduffkc. This is now merged into 6.1.x and main. It would be awesome if you could try 6.1.6-SNAPSHOT (the updated version will be available in a few minutes) and let us know if that is really fixed.

@burghduffkc
Copy link
Author

@marcusdacoregio I tested the snapshot and was able to verify the issue was fixed. Thanks for the quick turnaround!!!

@acutus
Copy link

acutus commented Nov 26, 2024

Hi,

It seems this fix might have broken backwards compatibility with jakarta servlet 5, as it uses the new Cookie#setAttribute()-method.

At least when using a cookieCustomizer(like mentioned in an earlier comment) to set SameSite-attribute, upgrading to spring-security-web:6.1.9causes the error below. Downgrading to spring-security-web:6.1.5 fixes the issue.

2024-11-26 16:24:18 java.lang.NoSuchMethodError: 'void jakarta.servlet.http.Cookie.setAttribute(java.lang.String, java.lang.String)'
2024-11-26 16:24:18     at org.springframework.security.web.csrf.CookieCsrfTokenRepository.mapToCookie(CookieCsrfTokenRepository.java:200)

@marcusdacoregio I assume this was unintentional and servlet 5 should be supported, but wanted to make sure before raising a new issue about this?

@marcusdacoregio
Copy link
Contributor

Hi @acutus, please go ahead and create a new ticket

@acutus
Copy link

acutus commented Nov 26, 2024

Will do

@acutus
Copy link

acutus commented Nov 26, 2024

Created #16173

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web An issue in web modules (web, webmvc) type: bug A general bug
Projects
Status: No status
Development

No branches or pull requests

3 participants