Skip to content

🐛 fix(csrf): port CORS subdomain match fixes - #4455

Merged
ReneWerner87 merged 5 commits into
mainfrom
claude/cors-csrf-subdomain-parity-ae2n3e
Jun 25, 2026
Merged

ReneWerner87 merged 5 commits into
mainfrom
claude/cors-csrf-subdomain-parity-ae2n3e

Conversation

@gaby

@gaby gaby commented Jun 25, 2026

Copy link
Copy Markdown
Member

The subdomain.match() in middleware/csrf/helpers.go was identical to the
CORS one but missed two security fixes applied on 2026-06-18 to
middleware/cors/utils.go:

  • bae48f0: reject empty wildcard labels via strings.HasSuffix(sub, ".")
  • 1b961aa: validate origins with normalizeOrigin() before matching

This brings the CSRF subdomain matcher to parity with CORS and adds the
corresponding regression tests.

claude added 2 commits June 24, 2026 23:39
The subdomain.match() in middleware/csrf/helpers.go was identical to the
CORS one but missed two security fixes applied on 2026-06-18 to
middleware/cors/utils.go:

- bae48f0: reject empty wildcard labels via strings.HasSuffix(sub, ".")
- 1b961aa: validate origins with normalizeOrigin() before matching

This brings the CSRF subdomain matcher to parity with CORS and adds the
corresponding regression tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QaVJcHsCGZBkYcSP9GhCU7
CORS normalizeOrigin rejects origins containing userinfo
(parsedOrigin.User != nil), but the CSRF copy did not, silently
stripping credentials and treating http://user:pass@example.com as a
valid http://example.com. Port the guard and its test.

Also add regression cases to both CORS and CSRF subdomain.match suites
covering userinfo-bearing and non-normalized (uppercase) origins.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QaVJcHsCGZBkYcSP9GhCU7
@gaby
gaby requested a review from a team as a code owner June 25, 2026 05:47
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

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: 1b16f401-fdf3-453d-ae61-42b4b78a82fd

📥 Commits

Reviewing files that changed from the base of the PR and between 41e1307 and 6340cd5.

📒 Files selected for processing (3)
  • middleware/csrf/storage_manager.go
  • middleware/csrf/storage_manager_msgp.go
  • middleware/csrf/storage_manager_msgp_test.go
💤 Files with no reviewable changes (3)
  • middleware/csrf/storage_manager_msgp_test.go
  • middleware/csrf/storage_manager_msgp.go
  • middleware/csrf/storage_manager.go

Walkthrough

The PR tightens CSRF origin validation, updates CORS subdomain test coverage, and removes CSRF storage manager pooling and msgp scaffolding.

Changes

Origin normalization and matching

Layer / File(s) Summary
Normalize and validate origins
middleware/csrf/helpers.go, middleware/csrf/helpers_test.go
normalizeOrigin rejects userinfo, subdomain.match requires normalized origins, and the label checks reject leading, trailing, or repeated dots. The CSRF tests add matching negative cases.
CORS test coverage cleanup
middleware/cors/utils.go, middleware/cors/utils_test.go
The CORS helper functions are removed, and the subdomain match tests now assert false for userinfo and uppercase-host origins.

CSRF storage manager cleanup

Layer / File(s) Summary
Remove msgp pooling scaffolding
middleware/csrf/storage_manager.go
storageManager drops the pool-backed allocation setup, and newStorageManager now only sets shouldRedactKeys and chooses the storage backend.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • gofiber/fiber#3690: Modifies CORS subdomain and wildcard matching behavior, which overlaps with the CORS subdomain test coverage updated here.
  • gofiber/fiber#3694: Touches the same CSRF origin/subdomain matching path in middleware/csrf/helpers.go.
  • gofiber/fiber#4438: Also tightens subdomain.match by requiring normalized origin input and adds related negative tests.

Suggested reviewers

  • sixcolors
  • efectn
  • ReneWerner87

Poem

🐰 I hopped through origins by moonlit stream,
and trimmed the paths to a tidier theme.
Userinfo? No, that bunny’s out!
Uppercase tricks won’t spin me about.
Now matches land neat in my burrowed dream.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the goal, but it omits the required template sections like Fixes #, changes list, type of change, and checklist. Add the template sections with an issue reference, detailed changes, type of change, and checklist items, or adapt the repo template explicitly.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the main CSRF subdomain match fix.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/cors-csrf-subdomain-parity-ae2n3e

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.

@ReneWerner87 ReneWerner87 added this to v3 Jun 25, 2026
@ReneWerner87 ReneWerner87 added this to the v3 milestone Jun 25, 2026
@gaby gaby changed the title fix(csrf): port CORS subdomain match security patches 🐛 fix(csrf): port CORS subdomain match fixes Jun 25, 2026
@codecov

codecov Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.64%. Comparing base (b24334e) to head (d3ab638).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4455      +/-   ##
==========================================
+ Coverage   91.62%   91.64%   +0.01%     
==========================================
  Files         134      134              
  Lines       13500    13487      -13     
==========================================
- Hits        12370    12360      -10     
+ Misses        721      719       -2     
+ Partials      409      408       -1     
Flag Coverage Δ
unittests 91.64% <100.00%> (+0.01%) ⬆️

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

☔ View full report in Codecov by Harness.
📢 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.

Both unexported helpers had zero production callers and were referenced
only by their own tests. subdomain.match now relies on normalizeOrigin
instead of matchScheme, and normalizeDomain was never wired into the
middleware. Remove the functions and their Test_MatchScheme /
Test_NormalizeDomain tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QaVJcHsCGZBkYcSP9GhCU7
claude and others added 2 commits June 25, 2026 05:59
storageManager.pool was initialized but never Get/Put. Its only purpose
was producing *item values, and the empty item struct existed solely to
feed that pool. Removing pool makes item dead, which in turn makes its
generated msgp serialization code (storage_manager_msgp.go and its test)
dead. Drop the pool field, the item type, the msgp generate directives,
the now-unused sync import, and the two generated files.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QaVJcHsCGZBkYcSP9GhCU7
@ReneWerner87
ReneWerner87 merged commit 6f77383 into main Jun 25, 2026
20 checks passed
@ReneWerner87
ReneWerner87 deleted the claude/cors-csrf-subdomain-parity-ae2n3e branch June 25, 2026 06:46
@github-project-automation github-project-automation Bot moved this to Done in v3 Jun 25, 2026
@ReneWerner87 ReneWerner87 modified the milestones: v3, v3.4.0 Jul 2, 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.

3 participants