Spring Security
CSRF Protection
HttpOnly
Web Security
Cookie Management

What does Cookie CsrfTokenRepository.withHttpOnlyFalse do and when to use it?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

CookieCsrfTokenRepository.withHttpOnlyFalse() is a Spring Security helper for one specific integration pattern: a browser-based frontend needs to read the CSRF token from a cookie and send it back in a request header. It does not disable CSRF protection. It only makes the CSRF cookie readable to JavaScript.

What the Method Changes

When Spring Security stores the CSRF token in a cookie, that cookie can be marked HttpOnly or not.

  • 'HttpOnly=true means browser JavaScript cannot read the cookie.'
  • 'HttpOnly=false means JavaScript can read it through document.cookie.'

Calling withHttpOnlyFalse() creates a CookieCsrfTokenRepository configured with HttpOnly=false for the CSRF token cookie.

Typical configuration:

java
1import org.springframework.context.annotation.Bean;
2import org.springframework.security.config.annotation.web.builders.HttpSecurity;
3import org.springframework.security.web.SecurityFilterChain;
4import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
5
6@Bean
7SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
8    http
9        .csrf(csrf -> csrf
10            .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
11        );
12
13    return http.build();
14}

CSRF validation still happens normally. The only difference is that frontend code can now read the token cookie and place the token in a header such as X-XSRF-TOKEN.

When to Use It

The most common use case is a single-page application or JavaScript-heavy frontend that authenticates with cookies and sends fetch or XMLHttpRequest calls to a Spring backend.

In that setup, the browser may receive a CSRF cookie like XSRF-TOKEN, and the frontend reads it before sending a state-changing request:

javascript
1function getCookie(name) {
2  return document.cookie
3    .split("; ")
4    .find(part => part.startsWith(name + "="))
5    ?.split("=")[1];
6}
7
8async function saveProfile(payload) {
9  const token = getCookie("XSRF-TOKEN");
10
11  const response = await fetch("/api/profile", {
12    method: "POST",
13    headers: {
14      "Content-Type": "application/json",
15      "X-XSRF-TOKEN": token
16    },
17    body: JSON.stringify(payload)
18  });
19
20  if (!response.ok) {
21    throw new Error("Request failed");
22  }
23}

Without a readable cookie, the frontend has no convenient way to obtain the token unless the server exposes it through another response channel.

When You Usually Should Not Use It

If the application is server-rendered and the CSRF token is already placed into forms by the backend, you often do not need a JavaScript-readable CSRF cookie at all.

Example:

html
1<form method="post" action="/orders">
2  <input type="hidden" name="_csrf" value="token-from-server">
3  <button type="submit">Submit</button>
4</form>

In that model, keeping the cookie HttpOnly is usually preferable because JavaScript does not need to read it.

Security Tradeoff

Setting HttpOnly=false does not break CSRF protection by itself, but it does make the token available to any script running in the page. That matters because an XSS bug could let malicious script read the token and send it along with forged requests.

So the method is appropriate when the frontend genuinely needs the token, but it should be paired with solid XSS defenses:

  • output encoding
  • Content Security Policy
  • careful handling of untrusted HTML
  • avoiding unsafe inline script patterns

The method solves a frontend integration problem. It is not a blanket recommendation for every Spring application.

Keep the Frontend and Backend Names Aligned

Spring commonly uses the cookie name XSRF-TOKEN and the header name X-XSRF-TOKEN. If you customize those names, the frontend must send exactly what the backend expects.

java
CookieCsrfTokenRepository repo = CookieCsrfTokenRepository.withHttpOnlyFalse();
repo.setCookieName("APP-CSRF");
repo.setHeaderName("X-APP-CSRF");

If the frontend still reads XSRF-TOKEN while the backend expects APP-CSRF, you will get 403 responses even though the feature is configured.

Common Pitfalls

The biggest pitfall is thinking withHttpOnlyFalse() turns off CSRF checks. It does not. It only changes whether JavaScript can read the token cookie.

Another common mistake is enabling it in a server-rendered application that already submits the token in forms. In that case, the readable cookie may add exposure without solving a real problem.

Developers also sometimes forget the second half of the flow: the frontend must actually copy the token into the expected request header on state-changing requests.

Finally, do not overlook XSS. A readable CSRF token is acceptable in many SPA setups, but only if the rest of the application treats browser-side script injection seriously.

Summary

  • 'withHttpOnlyFalse() makes the CSRF cookie readable by browser JavaScript.'
  • It is mainly useful for SPAs or JavaScript clients that need to send the token in a header.
  • It does not disable CSRF protection.
  • Avoid it when server-rendered forms already provide the token safely.
  • Use it with good XSS defenses and matching cookie or header names on both sides.

Course illustration
Course illustration

All Rights Reserved.