Skip to content

🐛 fix(csrf): strip path from referer before matching trusted origins#4204

Merged
ReneWerner87 merged 4 commits into
gofiber:mainfrom
aviu16:fix/csrf-referer-origin-matching
Apr 11, 2026
Merged

🐛 fix(csrf): strip path from referer before matching trusted origins#4204
ReneWerner87 merged 4 commits into
gofiber:mainfrom
aviu16:fix/csrf-referer-origin-matching

Conversation

@aviu16

@aviu16 aviu16 commented Apr 10, 2026

Copy link
Copy Markdown
Contributor

What happened

refererMatchesHost compares the full referer URL (including path and query string) against trustedOrigins and trustedSubOrigins. Since trusted origins are stored without paths (e.g. https://example.com), a referer like https://example.com/form/submit never matches via slices.Contains or subdomain.match (which uses strings.HasSuffix).

originMatchesHost doesn't have this problem because Origin headers omit the path per the HTTP spec.

This means CSRF protection falls back to rejecting all cross-origin requests from trusted origins when the browser sends a Referer instead of an Origin header.

Fix

Extract scheme://host from the parsed referer URL before comparing against trusted origins, matching how originMatchesHost already works.

Test

Added a test case that sends a trusted referer with a path component and verifies it returns 200 instead of 403.

refererMatchesHost compared the full referer URL (including path and
query) against trustedOrigins and trustedSubOrigins. Since trusted
origins are stored without paths (e.g. https://example.com), a referer
like https://example.com/form/submit never matched.

Extract only scheme://host from the parsed referer URL before comparing,
matching the behavior of originMatchesHost which already works correctly
because Origin headers omit the path per the HTTP spec.

Added a test case for trusted referer with path component.
@coderabbitai

coderabbitai Bot commented Apr 10, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d684629a-f63a-4178-b867-10db501667d1

📥 Commits

Reviewing files that changed from the base of the PR and between dc31002 and ba32016.

📒 Files selected for processing (2)
  • middleware/csrf/csrf.go
  • middleware/csrf/csrf_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • middleware/csrf/csrf.go
  • middleware/csrf/csrf_test.go

Walkthrough

refererMatchesHost now derives a normalized origin (scheme://host) from the Referer and uses that origin for trusted-origin and subdomain checks. Tests were extended to ensure Referer values with paths and queries are accepted when matching trusted origins.

Changes

Cohort / File(s) Summary
CSRF Origin Matching Logic
middleware/csrf/csrf.go
refererMatchesHost now constructs and uses a normalized origin (scheme://host, lowercased) for membership checks in trustedOrigins and passes that origin into the subdomain matcher instead of the full Referer URL.
CSRF Test Coverage
middleware/csrf/csrf_test.go
Expanded Test_CSRF_TrustedOrigins with cases that include Referer values containing path and query components for both exact and wildcard trusted origins; resets request/response state and sets CSRF token cookie/header for each case.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

codex

Suggested reviewers

  • sixcolors
  • ReneWerner87

Poem

🐰 I nibbled the referer, trimmed the maze,
Scheme and host in tidy, humble ways.
Paths and queries hop along,
Trusted origins sing my song.
Safe tokens, safe garden — hop on, hooray! 🥕

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description clearly explains the problem, fix, and test added. However, it does not follow the repository's description template structure with required sections like 'Changes introduced', 'Type of change', and 'Checklist'. Restructure the description to match the template: add 'Changes introduced' section, select appropriate 'Type of change' checkbox, and complete the 'Checklist' items with explicit selections.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: stripping the path from the referer URL before matching against trusted origins, which is the core fix in the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ReneWerner87 ReneWerner87 added this to v3 Apr 10, 2026
@ReneWerner87 ReneWerner87 added this to the v3 milestone Apr 10, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the CSRF middleware to extract and compare only the origin (scheme and host) from the Referer header, ensuring that paths or query parameters do not cause false negatives when validating against trusted origins. A test case was added to verify this fix. Feedback was provided to remove redundant string lowercasing operations to optimize performance and reduce allocations.

Comment thread middleware/csrf/csrf.go Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
middleware/csrf/csrf_test.go (1)

1340-1354: Add one more case for wildcard trusted referer with path.

This new case validates exact trusted origin + path, but the same regression path also exists for wildcard trusted referers. Please add a https://safe.domain-1.com/some/path?... case to exercise the wildcard branch too.

🧪 Suggested additional test case
+	// Test Trusted Referer Wildcard with path
+	ctx.Request.Reset()
+	ctx.Response.Reset()
+	ctx.Request.Header.SetMethod(fiber.MethodPost)
+	ctx.Request.Header.Set(fiber.HeaderXForwardedProto, "https")
+	ctx.Request.URI().SetScheme("https")
+	ctx.Request.URI().SetHost("domain-1.com")
+	ctx.Request.Header.SetProtocol("https")
+	ctx.Request.Header.SetHost("domain-1.com")
+	ctx.Request.Header.Set(fiber.HeaderReferer, "https://safe.domain-1.com/some/path?q=1")
+	ctx.Request.Header.Set(HeaderName, token)
+	ctx.Request.Header.SetCookie(ConfigDefault.CookieName, token)
+	h(ctx)
+	require.Equal(t, 200, ctx.Response.StatusCode())
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@middleware/csrf/csrf_test.go` around lines 1340 - 1354, Add a new test case
mirroring the existing "Trusted Referer with path" block but using a
wildcard-trusted origin host (e.g. set
ctx.Request.Header.Set(fiber.HeaderReferer,
"https://safe.domain-1.com/some/path?q=1")) so the wildcard matching branch is
exercised; keep the same request setup (Reset(), MethodPost,
X-Forwarded-Proto=https, URI scheme/host, Header Host, HeaderName and
ConfigDefault.CookieName set to token), call h(ctx) and assert require.Equal(t,
200, ctx.Response.StatusCode()) to validate the wildcard referer path handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@middleware/csrf/csrf_test.go`:
- Around line 1340-1354: Add a new test case mirroring the existing "Trusted
Referer with path" block but using a wildcard-trusted origin host (e.g. set
ctx.Request.Header.Set(fiber.HeaderReferer,
"https://safe.domain-1.com/some/path?q=1")) so the wildcard matching branch is
exercised; keep the same request setup (Reset(), MethodPost,
X-Forwarded-Proto=https, URI scheme/host, Header Host, HeaderName and
ConfigDefault.CookieName set to token), call h(ctx) and assert require.Equal(t,
200, ctx.Response.StatusCode()) to validate the wildcard referer path handling.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: b9743f6b-a903-4a0e-93ef-bfc924350258

📥 Commits

Reviewing files that changed from the base of the PR and between cf37114 and dc31002.

📒 Files selected for processing (2)
  • middleware/csrf/csrf.go
  • middleware/csrf/csrf_test.go

@gaby gaby changed the title fix(csrf): strip path from referer before matching trusted origins 🐛 fix(csrf): strip path from referer before matching trusted origins Apr 10, 2026
@gaby
gaby requested a review from Copilot April 10, 2026 03:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes CSRF trusted-origin matching when browsers send a Referer header that includes a path/query by comparing only scheme://host (aligned with how Origin is matched).

Changes:

  • Normalize Referer to scheme://host before checking trustedOrigins and trustedSubOrigins.
  • Add a regression test ensuring a trusted referer containing a path/query is accepted (200 vs 403).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
middleware/csrf/csrf.go Strips path/query from parsed referer URL by comparing only scheme://host to trusted origin allowlists.
middleware/csrf/csrf_test.go Adds a test case covering trusted referer matching when the referer includes a path/query.

referer is already lowercased at line 376 before parsing, so the
per-component ToLower calls are unnecessary.

Also added a test for wildcard trusted subdomain with path+query in
the referer to cover the subdomain.match path.

@sixcolors sixcolors left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Normalizing Referer to an origin (scheme://host) before checking trustedOrigins/wildcards is the right behavior, and the new tests cover the regression nicely.

@gaby

gaby commented Apr 10, 2026

Copy link
Copy Markdown
Member

Merge pending fixes to Fiber. The CI failing are related to a recently merged PR.

@codecov

codecov Bot commented Apr 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.21%. Comparing base (5de4c35) to head (a274da0).
⚠️ Report is 8 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4204      +/-   ##
==========================================
+ Coverage   91.15%   91.21%   +0.06%     
==========================================
  Files         123      123              
  Lines       11855    11855              
==========================================
+ Hits        10806    10814       +8     
+ Misses        660      654       -6     
+ Partials      389      387       -2     
Flag Coverage Δ
unittests 91.21% <100.00%> (+0.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ReneWerner87
ReneWerner87 merged commit 6c19f48 into gofiber:main Apr 11, 2026
19 of 20 checks passed
@welcome

welcome Bot commented Apr 11, 2026

Copy link
Copy Markdown

Congrats on merging your first pull request! 🎉 We here at Fiber are proud of you! If you need help or want to chat with us, join us on Discord https://gofiber.io/discord

@github-project-automation github-project-automation Bot moved this to Done in v3 Apr 11, 2026
@ReneWerner87 ReneWerner87 modified the milestones: v3, v3.2.0 Apr 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants