Skip to content

Fix 403 Forbidden: CSRF cookie subdomain sharing + explicit path for hybrid JWT architecture#43

Merged
vitorhugo-java merged 3 commits intomasterfrom
copilot/fix-403-forbidden-error
Mar 13, 2026
Merged

Fix 403 Forbidden: CSRF cookie subdomain sharing + explicit path for hybrid JWT architecture#43
vitorhugo-java merged 3 commits intomasterfrom
copilot/fix-403-forbidden-error

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 13, 2026

The XSRF-TOKEN cookie set by api.espacogeek.com was not readable by espacogeek.com due 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.java

  • Explicitly call csrfRepo.setCookiePath("/") — without this, the path defaults to servlet context path which may not be / in all deployment scenarios
  • Remove unused UrlBasedCorsConfigurationSource import

application.properties

  • Add security.csrf.cookie-domain=${CSRF_COOKIE_DOMAIN:} — set to .espacogeek.com in production so the XSRF-TOKEN cookie is shared across subdomains:
    # production env var:
    CSRF_COOKIE_DOMAIN=.espacogeek.com
  • Add security.csrf.cookie-same-site=${CSRF_COOKIE_SAME_SITE:} — allows tuning the SameSite attribute when deploying across origins (e.g. None for cross-site)

Architecture already in place (unchanged)

  • CSRF bypass via ignoringRequestMatchers when Authorization: Bearer is present (mobile/Flutter/Postman)
  • CsrfTokenRequestAttributeHandler (plain, non-XOR) for SPA double-submit-cookie compatibility
  • JwtAuthenticationFilter reads JWT from Authorization header first, falls back to EG_AUTH HttpOnly 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.

…operties

Co-authored-by: vitorhugo-java <65777252+vitorhugo-java@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix 403 Forbidden error due to missing X-XSRF-TOKEN header Fix 403 Forbidden: CSRF cookie subdomain sharing + explicit path for hybrid JWT architecture Mar 13, 2026
Copilot AI requested a review from vitorhugo-java March 13, 2026 11:53
@github-actions
Copy link
Copy Markdown

Qodana for JVM

43 new problems were found

Inspection name Severity Problems
Unused assignment 🔶 Warning 16
Constant values 🔶 Warning 6
String comparison using '==', instead of 'equals()' 🔶 Warning 5
Optional.get() is called without isPresent() check 🔶 Warning 4
Boxing of already boxed value 🔶 Warning 2
Nullability and data flow problems 🔶 Warning 2
Mismatched query and update of collection 🔶 Warning 2
AutoCloseable used without 'try'-with-resources 🔶 Warning 1
Result of method call ignored 🔶 Warning 1
'long' literal ending with 'l' instead of 'L' 🔶 Warning 1
Use of Optional.ofNullable with null or non-null argument 🔶 Warning 1
Single character alternation 🔶 Warning 1
'if' statement with identical branches or common parts ◽️ Notice 1
View the detailed Qodana report

To be able to view the detailed Qodana report, you can either:

To get *.log files or any other Qodana artifacts, run the action with upload-result option set to true,
so that the action will upload the files as the job artifacts:

      - name: 'Qodana Scan'
        uses: JetBrains/qodana-action@v2025.3.1
        with:
          upload-result: true
Contact Qodana team

Contact us at qodana-support@jetbrains.com

@vitorhugo-java vitorhugo-java marked this pull request as ready for review March 13, 2026 12:14
Copilot AI review requested due to automatic review settings March 13, 2026 12:14
@vitorhugo-java vitorhugo-java merged commit d532953 into master Mar 13, 2026
4 checks passed
@vitorhugo-java vitorhugo-java deleted the copilot/fix-403-forbidden-error branch March 13, 2026 12:14
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 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 / in SecurityConfig to 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.

Comment on lines +46 to +48
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).
Comment on lines 81 to 85
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:}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants