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

CSRF validation fails because CSRFHandler updates the session AFTER the session is already flushed #2599

Open
haizz opened this issue Apr 15, 2024 · 0 comments
Labels

Comments

@haizz
Copy link

haizz commented Apr 15, 2024

Version

4.5.7

Context

Root cause seems to be in #2500 (#2447, #2460)

CSRFHandlerImpl updates the session with End Handler:

private String generateToken(RoutingContext ctx) {
    // ...
    ctx.addEndHandler(sessionTokenEndHandler(ctx, token));
    // ...
}

But SessionHandlerImpl flushes the session with HeadersEnd Handler

private void addStoreSessionHandler(RoutingContext context) {
    context.addHeadersEndHandler(v -> {
      // skip flush if we already flushed
      Boolean flushed = context.get(SESSION_FLUSHED_KEY);
      if (flushed == null || !flushed) {
        flush(context, true, false)
          .onFailure(err -> LOG.warn("Failed to flush the session to the underlying store", err));
      }
    });
  }

So SessionHandlerImpl flushes the session on headers end, and then CSRFHandlerImpl updates the already flushed session, and no changes end up being saved in the session store.

Tests work because LocalSessionStore store raw session objects in the map. So when you update the session object, no flush is needed: next time you retrieve updated session object from the store. It won't work when sessions are serialized/deserialized in the store.

@haizz haizz added the bug label Apr 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

1 participant