🐛 bug: Fix open redirect via Redirect().Back() — validate Referer header origin - #4370
Conversation
…irect Add same-origin validation to Redirect().Back() to reject cross-origin Referer headers that could lead to open redirect attacks. When the Referer contains a host that differs from the request's hostname, the fallback URL is used instead.
There was a problem hiding this comment.
Pull request overview
Fixes an open-redirect vulnerability in Redirect().Back() by validating that the Referer header points to the same host as the current request before using it as the Location. Cross-origin or unparseable referers now fall through to the provided fallback URL (or ErrRedirectBackNoFallback).
Changes:
redirect.go: ParseRefererand reject whenparsed.Hostname() != r.c.Hostname()(relative referers, with no host, are still accepted).redirect_test.go: AddTest_Redirect_Back_WithCrossOriginReferercovering cross-origin rejection (with and without fallback), same-origin acceptance, and relative-path acceptance.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| redirect.go | Validates Referer URL host against current host in Back(), treating cross-origin/invalid referers as missing. |
| redirect_test.go | Adds tests for cross-origin rejection, missing-fallback error, same-origin acceptance, and relative path acceptance. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4370 +/- ##
==========================================
- Coverage 91.37% 91.33% -0.04%
==========================================
Files 132 132
Lines 13161 13193 +32
==========================================
+ Hits 12026 12050 +24
- Misses 719 724 +5
- Partials 416 419 +3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@copilot The Referer-based same-origin check currently compares only the hostname, which leaves two gaps:
Please compare the full origin tuple (scheme, host, port) of the parsed Referer against the current request, and reject when any of the three differs. After that, please fix the failing checks: |
Addressed in 1dc23db. The branch compares scheme + host + port for |
|
@copilot Good news: the redirect change itself is fine, all of Linter, Spell check, govulncheck and Benchmark are green. The only red check is the Test job on
That is a Windows-only cache date-clamping test and has nothing to do with |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
@copilot fix cspell workflow |
Fixed in |
|
@copilot audit the security of Redirect().Back() |
Security audit of Validation logic (line 384–389):
Other observations:
|
Description
Redirect().Back()reads theRefererheader and sets it as theLocationheader without validation. An attacker can craft a request withReferer: https://evil.com/phishingto redirect users to a malicious site (phishing, OAuth token theft, credential harvesting).The fix now validates the full Referer origin tuple before using it: scheme, host, and port. Cross-origin referrers are rejected and the fallback URL is used instead. Relative paths are always accepted since they're inherently same-origin. Non-hierarchical scheme-only values such as
javascript:...andmailto:...are also rejected. Default ports are normalized sohttp://example.commatcheshttp://example.com:80, andhttps://example.commatcheshttps://example.com:443.Changes introduced
redirect.go: Parse theRefererURL and compare its full origin tuple (scheme,host,port) against the current request. Reject invalid or cross-origin values, reject scheme-only non-hierarchical URIs, and treat default ports (80/443) as equivalent to omitted ports.redirect_test.go: AddTest_Redirect_Back_WithCrossOriginReferercoverage for cross-host rejection, no-fallback error handling, same-origin acceptance, default-port acceptance, cross-scheme rejection, cross-port rejection, relative path acceptance, and scheme-only referrer rejection.redirect_test.go: Correct test comment spelling to satisfy the cspell workflow without changing behavior.Benchmarks: No new allocations on the happy path (relative referrers skip
url.Parseonly when host is absent). Oneurl.Parsecall is used for absolute referrers.Documentation Update: The
docs/api/redirect.mdBack section could note the full same-origin validation; behavior is otherwise unchanged.Changelog/What's New:
Redirect().Back()now validates full same-origin (scheme,host,port) on theRefererheader and rejects scheme-only non-hierarchical values to prevent open redirects.Migration Guide: No breaking changes. Cross-origin or invalid
Referervalues that previously triggered a redirect will now fall through to the fallback URL.API Alignment with Express: Express
res.redirect('back')has the same vulnerability; this is a security improvement over Express behavior.API Longevity: Validation is internal; public API signature is unchanged.
Examples: See code snippet above.
Type of change
Checklist
/docs/directory for Fiber's documentation.Commit formatting
🔒 Security fix — open redirect prevention via full same-origin Referer validation and rejection of invalid scheme-only referrers.