Fix 403 Forbidden: CSRF cookie subdomain sharing + explicit path for hybrid JWT architecture#43
Conversation
…operties Co-authored-by: vitorhugo-java <65777252+vitorhugo-java@users.noreply.github.com>
Qodana for JVM43 new problems were found
View the detailed Qodana reportTo be able to view the detailed Qodana report, you can either:
To get - name: 'Qodana Scan'
uses: JetBrains/qodana-action@v2025.3.1
with:
upload-result: trueContact Qodana teamContact us at qodana-support@jetbrains.com
|
There was a problem hiding this comment.
Pull request overview
This PR addresses browser 403s caused by CSRF double-submit cookie scope issues in a hybrid JWT + cookie architecture, by making CSRF cookie scoping configurable and ensuring the cookie is valid across subdomains.
Changes:
- Add CSRF cookie configuration properties for Domain and SameSite in
application.properties. - Force the CSRF cookie Path to
/inSecurityConfigto avoid context-path-dependent scoping. - Remove an unused CORS-related import.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/main/resources/application.properties | Introduces CSRF cookie Domain/SameSite configuration knobs via properties/env placeholders. |
| src/main/java/com/espacogeek/geek/config/SecurityConfig.java | Forces CSRF cookie path to / and keeps CSRF cookie Domain/SameSite configurable; removes unused import. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| security.csrf.cookie-domain=${SECURITY_CSRF_COOKIE_DOMAIN:} | ||
| # CSRF cookie SameSite attribute (e.g., None for cross-site, Lax for same-site). | ||
| security.csrf.cookie-same-site=${SECURITY_CSRF_COOKIE_SAME_SITE:} |
| # is accessible to both api.espacogeek.com (backend) and espacogeek.com (frontend). | ||
| # Leave blank for local development. | ||
| security.csrf.cookie-domain=${SECURITY_CSRF_COOKIE_DOMAIN:} | ||
| # CSRF cookie SameSite attribute (e.g., None for cross-site, Lax for same-site). |
| var csrfRepo = CookieCsrfTokenRepository.withHttpOnlyFalse(); | ||
| csrfRepo.setCookiePath("/"); | ||
| if (!csrfCookieDomain.isBlank()) { | ||
| csrfRepo.setCookieDomain(csrfCookieDomain); | ||
| } |
| # Leave blank for local development. | ||
| security.csrf.cookie-domain=${SECURITY_CSRF_COOKIE_DOMAIN:} | ||
| # CSRF cookie SameSite attribute (e.g., None for cross-site, Lax for same-site). | ||
| security.csrf.cookie-same-site=${SECURITY_CSRF_COOKIE_SAME_SITE:} |
The
XSRF-TOKENcookie set byapi.espacogeek.comwas not readable byespacogeek.comdue to Same-Origin Policy, causing browsers to fail the CSRF double-submit check and receive 403s. The fix exposes the two missing configuration knobs and sets the CSRF cookie path explicitly.Changes
SecurityConfig.javacsrfRepo.setCookiePath("/")— without this, the path defaults to servlet context path which may not be/in all deployment scenariosUrlBasedCorsConfigurationSourceimportapplication.propertiessecurity.csrf.cookie-domain=${CSRF_COOKIE_DOMAIN:}— set to.espacogeek.comin production so theXSRF-TOKENcookie is shared across subdomains:security.csrf.cookie-same-site=${CSRF_COOKIE_SAME_SITE:}— allows tuning the SameSite attribute when deploying across origins (e.g.Nonefor cross-site)Architecture already in place (unchanged)
ignoringRequestMatcherswhenAuthorization: Beareris present (mobile/Flutter/Postman)CsrfTokenRequestAttributeHandler(plain, non-XOR) for SPA double-submit-cookie compatibilityJwtAuthenticationFilterreads JWT fromAuthorizationheader first, falls back toEG_AUTHHttpOnly cookie✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.