CSRF handling: changes from 24.7 to 24.8?

Hi!
Has something changed in the CSRF handling from 24.7 to 24.8? I do not really need it since I use stateless JWT authentication for my own endpoints but since I updated from 24.7.5 to 24.8.0.beta2 I get problems after logging in into my app, apparently because the renewed CSRF token does not make it into the browser and subsequent calls to /connect/** fail. Refreshing the page after login helps, but for now I probably have to disable CSRF for /connect/**

Thanks in advance
Olaf

[nio-8183-exec-6] o.s.s.w.savedrequest.CookieRequestCache  : saved request doesn't match
[nio-8183-exec-6] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
[nio-8183-exec-6] o.s.security.web.FilterChainProxy        : Secured GET /VAADIN/push?v-r=push&debug_window&token=ad41cd95-46d5-4d3b-acbd-3b484c19f17f&X-Atmosphere-tracking-id=0&....
[nio-8183-exec-4] o.s.security.web.FilterChainProxy        : Securing POST /connect/UiSettingsService/fetchUiSettings
[nio-8183-exec-5] o.s.w.r.f.client.ExchangeFunctions       : [5e643950] HTTP GET http://localhost:8130/internal/v1/subscriptions/....
[r-http-epoll-33] o.s.w.r.f.client.ExchangeFunctions       : [5e643950] [07da98fc-2] Response 200 OK
[r-http-epoll-33] org.springframework.web.HttpLogging      : [5e643950] [07da98fc-2] Decoded [ (truncated)...]
[nio-8183-exec-5] o.s.w.r.f.client.ExchangeFunctions       : [19735b97] HTTP GET http://localhost:8130/internal/v1/users/...
[or-http-epoll-9] o.s.w.r.f.client.ExchangeFunctions       : [19735b97] [c4c32d30-61] Response 200 OK
[or-http-epoll-9] org.springframework.web.HttpLogging      : [19735b97] [c4c32d30-61] Decoded [User(authProviderId=firebase, (truncated)...]
[nio-8183-exec-5] o.s.s.w.savedrequest.CookieRequestCache  : saved request doesn't match
[nio-8183-exec-5] .s.ChangeSessionIdAuthenticationStrategy : Changed session id from FB9F373CD166885EF1A71EBE9C153699
[nio-8183-exec-5] o.s.s.w.csrf.CsrfAuthenticationStrategy  : Replaced CSRF Token
[nio-8183-exec-4] o.s.s.w.savedrequest.CookieRequestCache  : saved request doesn't match
[nio-8183-exec-4] o.s.s.w.csrf.CsrfAuthenticationStrategy  : Replaced CSRF Token
[...]
[nio-8183-exec-2] o.s.security.web.FilterChainProxy        : Securing POST /connect/UiSettingsService/getAvailableLanguages
[nio-8183-exec-2] o.s.security.web.csrf.CsrfFilter         : Invalid CSRF token found for http://localhost:8183/connect/UiSettingsService/getAvailableLanguages
[nio-8183-exec-3] o.s.security.web.FilterChainProxy        : Securing POST /connect/UiSettingsService/getAvailableCountries
[nio-8183-exec-3] o.s.security.web.csrf.CsrfFilter         : Invalid CSRF token found for http://localhost:8183/connect/UiSettingsService/getAvailableCountries
[io-8183-exec-10] o.s.security.web.FilterChainProxy        : Securing POST /connect/CurrencyService/getAvailableCurrencies
[io-8183-exec-10] o.s.security.web.csrf.CsrfFilter         : Invalid CSRF token found for http://localhost:8183/connect/CurrencyService/getAvailableCurrencies
[nio-8183-exec-8] o.s.security.web.FilterChainProxy        : Securing POST /connect/UiSettingsService/getAvailableTimeZones
[nio-8183-exec-8] o.s.security.web.csrf.CsrfFilter         : Invalid CSRF token found for http://localhost:8183/connect/UiSettingsService/getAvailableTimeZones

Hi, thanks for the report.

Is it so that your application updates CSRF meta tags in the document head dynamically after login?

The CSRF implementation in 24.8 is not using update automatically. I think the best we could do here is provide an API to reset the stored value in the Hilla client using meta tags. Would it help?

I do not touch any meta tags. I have a Middleware which sets the JWT in the Bearer authorization. That’s it.

An API would definitely help because I could easily add a CSRF Middleware to the ConnectClient. Another thing is that the CSRF apparently returns a 401 instead of a 403 so that it would be difficult to distinguish CSRF from real 401. On the other hand, I do not really know where this 401 comes from.

Update: Or is the 401 is correct in this situation? It’s just my case with authentication separated from the CSRF protection so that I expected a 403. But from the point of view of the Hilla app a 401 seems to be correct.

POST http://localhost:8183/connect/UiSettingsService/getAvailableCountries 401 (Unauthorized)
copilotMiddleware	@	vaadin.ts:44
BearerMiddleware	@	bearer-middleware.ts:45
await in call		
getAvailableCountries_1	@	UiSettingsService.ts:8

401 for blocked CSRF sounds more right to me - the request was denied because it couldn’t be authenticated. 403 would be “we have authenticated you and you don’t have rights to access this resource”.

Thanks for the clarification. I was thinking that rather than trying to handle CSRF error response, the error could be prevented if Hilla would handle the session change during login.

Naturally if the page is reloaded after login, the new token is obtained through index.html request, and the session change is handled this wa. But from the information so far I assume that the login process in your application does not produce a page reload, and thus you have an issue.

Given that you don’t touch meta tags, I guess that Spring Security configured to use CookieCsrfTokenRepository or similar? If so, Hilla client could probably support it and use the up-to-date token automatically from the cookies.

However, if JWT Bearer authorization is required for endpoints, then CSRF protection for Hilla endpoints is indeed unnecessary. So disabling CSRF for Hilla endpoints also makes sense as an alternative.

No, I have a simple SecurityConfig with just an additional filter verifying the JWT. No cookies, no nothing.

I played an hour with a CSRF endpoint and a Middleware to update the header and the _csrf meta but to no avail. So, I disable CSRF for now.

Thanks for your reply.
Olaf

I found the following code in 24.5.7 → @vaadin/hilla-frontend/Connect.jsConnectClient#call

const csrfHeaders = getCsrfTokenHeadersForEndpointRequest(document);
const headers = {
  Accept: "application/json",
  "Content-Type": "application/json",
  ...csrfHeaders
};

Does this exist in 24.8?
Is the csrf token send on each endpoint request, visible in Chrome Dev Tools?