Skip to content

Fix double submit csrf cookie - #4010

Open
joemahady-comm wants to merge 1 commit into
cloudfoundry:developfrom
joemahady-comm:TNZGOV-15565
Open

Fix double submit csrf cookie#4010
joemahady-comm wants to merge 1 commit into
cloudfoundry:developfrom
joemahady-comm:TNZGOV-15565

Conversation

@joemahady-comm

@joemahady-comm joemahady-comm commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Ticket: double-submit-csrf-cookie-without-host-prefix-samesite-none-session

Fix: Adjusted CookieBasedCsrfTokenRepository to inject the __Host- prefix on the cookie name, strict / path, and Secure attribute dynamically whenever the connection is secure.

…-prefix-samesite-none-session / uaa ai-assisted=yes

Co-authored-by: Cursor <cursoragent@cursor.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates UAA’s CookieBasedCsrfTokenRepository to emit and read a __Host--prefixed CSRF cookie on secure requests, aligning cookie attributes (name/prefix, Secure, and Path) with modern browser expectations for stronger CSRF cookie handling.

Changes:

  • Generate __Host-<cookieName> on secure requests and use Path=/ for that cookie.
  • Adjust token loading logic to look for the secure vs non-secure cookie name depending on request security.
  • Update unit test helper logic to account for Spring Framework 7 MockHttpServletResponse cookie parsing changes.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
server/src/main/java/org/cloudfoundry/identity/uaa/security/web/CookieBasedCsrfTokenRepository.java Adds secure-aware cookie naming (__Host-), Secure flag, and Path selection; updates lookup logic accordingly.
server/src/test/java/org/cloudfoundry/identity/uaa/web/CookieBasedCsrfTokenRepositoryTests.java Updates test cookie extraction to handle Set-Cookie header parsing changes and introduces expectations around secure cookie naming.
Comments suppressed due to low confidence (2)

server/src/main/java/org/cloudfoundry/identity/uaa/security/web/CookieBasedCsrfTokenRepository.java:145

  • loadToken() uses the raw parameterName to build expectedCookieName. If parameterName is ever configured with a leading __Host-, secure requests will look for a double-prefixed cookie (__Host-__Host-…) and non-secure requests will look for a __Host-… cookie that browsers may reject. Normalize to an unprefixed base name (as in saveToken()) before applying __Host- based on request security.
                boolean isSecure = secure || "https".equals(request.getScheme());
                String expectedCookieName = isSecure ? "__Host-" + getParameterName() : getParameterName();

server/src/test/java/org/cloudfoundry/identity/uaa/web/CookieBasedCsrfTokenRepositoryTests.java:172

  • The changes introduce different cookie names and paths when the request is secure (__Host-… with Path=/). The current tests only assert the Secure/HttpOnly flags and don’t verify that the Set-Cookie header actually uses the expected __Host- name and Path=/ (or that non-secure requests keep the unprefixed name and context-path-based Path). Adding explicit assertions for these new behaviors would prevent regressions.
        boolean expectSecure = isSecure || "https".equals(protocol);
        String expectedCookieName = expectSecure ? "__Host-X-Uaa-Csrf" : "X-Uaa-Csrf";
        

Comment on lines +117 to +127
boolean isSecure = secure || "https".equals(request.getScheme());
String cookieName = isSecure ? "__Host-" + token.getParameterName() : token.getParameterName();

Cookie csrfCookie = new Cookie(cookieName, token.getToken());
csrfCookie.setHttpOnly(true);
csrfCookie.setSecure(secure || "https".equals(request.getScheme()));
csrfCookie.setPath(ofNullable(request.getContextPath()).orElse("") + "/");
csrfCookie.setSecure(isSecure);
if (cookieName.startsWith("__Host-")) {
csrfCookie.setPath("/");
} else {
csrfCookie.setPath(ofNullable(request.getContextPath()).orElse("") + "/");
}
Comment on lines +169 to +180
MockHttpServletResponse response = saveTokenAndReturnResponse(isSecure, protocol);
boolean expectSecure = isSecure || "https".equals(protocol);
String expectedCookieName = expectSecure ? "__Host-X-Uaa-Csrf" : "X-Uaa-Csrf";

String setCookie = response.getHeader("Set-Cookie");
if (setCookie != null && setCookie.contains(expectedCookieName + "=")) {
Cookie cookie = new Cookie(expectedCookieName, "");
cookie.setSecure(setCookie.contains("Secure"));
cookie.setHttpOnly(setCookie.contains("HttpOnly"));
return cookie;
}
return response.getCookie(expectedCookieName);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

2 participants