Skip to content

🐛 fix(proxy): backport BalancerForward X-Real-IP overwrite fix to v2 - #4495

Merged
ReneWerner87 merged 3 commits into
gofiber:v2from
terraincognita07:backport-v2-balancer-forward-x-real-ip
Jul 3, 2026
Merged

ReneWerner87 merged 3 commits into
gofiber:v2from
terraincognita07:backport-v2-balancer-forward-x-real-ip

Conversation

@terraincognita07

Copy link
Copy Markdown

Summary

Backports the v3 fix for GHSA-gcfq-8gqf-4876 / CVE-2026-45045 ("GoFiber
Vulnerable to X-Real-IP Spoofing via Header.Add() in BalancerForward") to the
v2 branch.

BalancerForward in middleware/proxy/proxy.go uses Header.Add("X-Real-IP", c.IP()) when forwarding a request to a backend. Because Add appends rather
than replaces, a client-supplied X-Real-IP header is not removed — it is
kept as the first value, with the real client IP appended as a second
value. Upstream servers that read only the first X-Real-IP value (nginx,
Express, and most HTTP servers) therefore trust the attacker-controlled value
for IP-based logging, rate limiting, ACLs, and geofencing, i.e. an
authentication/authorization-adjacent spoofing bypass (CWE-290).

The v3 branch was fixed in commit
1403cc8292da3220e9316960b4030cc722a0f396
(PR #4260, "fix(proxy): Ensure BalancerForward overwrites X-Real-IP header"),
released in v3.3.0. Per the advisory, v2's vulnerable_version_range is
<= 2.52.13 with no patched version published for github.com/gofiber/fiber/v2
— the v2 branch never received this fix. This PR closes that gap.

Change

One-line fix in middleware/proxy/proxy.go, BalancerForward: replace
Header.Add with Header.Set so any attacker-supplied X-Real-IP header is
overwritten with the real client IP (c.IP()) rather than retained alongside
it.

-		c.Request().Header.Add("X-Real-IP", c.IP())
+		c.Request().Header.Set("X-Real-IP", c.IP())

Also updates the matching code sample in docs/api/middleware/proxy.md (the
v2 equivalent of the doc fix in PR #4260), which showed the same insecure
Header.Add pattern, so the documented example doesn't teach the vulnerable
usage.

Test

Added Test_Proxy_Balancer_Forward_OverwritesXRealIP in
middleware/proxy/proxy_test.go, adapted from the v3 regression test added
in PR #4260 (Test_Proxy_Balancer_Forward_OverwritesXRealIP) to v2's
*fiber.Ctx pointer-receiver handler signature and the utils.AssertEqual
assertion helper used elsewhere in this file. The test sends a request
through BalancerForward with a spoofed X-Real-IP: 10.0.0.1 header already
set, and asserts the backend observes only the real (test-harness) client IP
and never the spoofed value.

Confirmed the test fails against the unpatched Header.Add call (backend
observes the spoofed 10.0.0.1 as the first header value) and passes once
Header.Set is restored.

Compatibility

Behavior-only fix, no signature or config changes. Any caller currently
relying on the buggy "spoofed value plus real value" double header (there is
no legitimate reason to) would see only the real client IP going forward,
which is the documented and intended behavior.

References

Found via a Dependabot alert on a consuming project.

Backport of the v3 fix (1403cc8, PR gofiber#4260) for GHSA-gcfq-8gqf-4876 /
CVE-2026-45045 to the v2 branch: Header.Add kept an attacker-supplied
X-Real-IP as the first header value, so upstream servers reading the
first value trusted the spoofed IP. Header.Set overwrites it with the
real client IP (c.IP()).

Adds the corresponding regression test adapted to v2's *fiber.Ctx
handler signature, and fixes the same insecure pattern in the proxy
middleware doc example.
@coderabbitai

coderabbitai Bot commented Jul 3, 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: ccd80833-8fc1-4f64-9ed2-2334a0fa80ae

📥 Commits

Reviewing files that changed from the base of the PR and between 7c064e3 and da6126b.

📒 Files selected for processing (1)
  • middleware/proxy/proxy_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • middleware/proxy/proxy_test.go

Walkthrough

BalancerForward now overwrites X-Real-IP with Header.Set instead of appending it. The matching documentation example is updated, and a new test verifies the proxied request carries the overwritten client IP.

Changes

X-Real-IP Overwrite Behavior

Layer / File(s) Summary
Overwrite X-Real-IP on forward
middleware/proxy/proxy.go, docs/api/middleware/proxy.md, middleware/proxy/proxy_test.go
BalancerForward now uses Header.Set("X-Real-IP", c.IP()) instead of Header.Add, the docs example matches that behavior, and a new test checks the target sees the overwritten header value.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Possibly related PRs

  • gofiber/fiber#4260: Changes the same BalancerForward header behavior, updates the matching docs example, and adds the overwrite test.

Suggested labels: 🧹 Updates, 📒 Documentation

Suggested reviewers: ReneWerner87, efectn, gaby

Poem

A bunny hopped through proxy land,
With headers tucked in paw and hand.
One real IP, neat and true,
No duplicate trails peeking through.
Hop! The tests went green with cheer.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states the backport and the X-Real-IP overwrite fix in BalancerForward.
Description check ✅ Passed The description thoroughly explains the security fix, implementation, test, and compatibility, with only minor template fields missing.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


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.

@gaby gaby changed the title fix(proxy): backport BalancerForward X-Real-IP overwrite fix to v2 (GHSA-gcfq-8gqf-4876) fix(proxy): backport BalancerForward X-Real-IP overwrite fix to v2 Jul 3, 2026
@gaby gaby changed the title fix(proxy): backport BalancerForward X-Real-IP overwrite fix to v2 🐛 fix(proxy): backport BalancerForward X-Real-IP overwrite fix to v2 Jul 3, 2026
@gaby

gaby commented Jul 3, 2026

Copy link
Copy Markdown
Member

@ReneWerner87 I dont think the CI for v2 works anymore.

@ReneWerner87

Copy link
Copy Markdown
Member

ok, let me fix this

@gaby

gaby commented Jul 3, 2026

Copy link
Copy Markdown
Member

Related #4219

@ReneWerner87 ReneWerner87 added the v3 label Jul 3, 2026
@ReneWerner87 ReneWerner87 added this to v3 Jul 3, 2026
@ReneWerner87 ReneWerner87 added this to the v3 milestone Jul 3, 2026
@ReneWerner87 ReneWerner87 added v3 and removed v3 labels Jul 3, 2026
@ReneWerner87 ReneWerner87 removed the v3 label Jul 3, 2026
@ReneWerner87 ReneWerner87 removed this from v3 Jul 3, 2026
@ReneWerner87 ReneWerner87 removed this from the v3 milestone Jul 3, 2026
@ReneWerner87
ReneWerner87 merged commit 33c9501 into gofiber:v2 Jul 3, 2026
16 checks passed
@welcome

welcome Bot commented Jul 3, 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

@aldok10

aldok10 commented Jul 6, 2026

Copy link
Copy Markdown

Hi maintainers,

Thanks for merging this backport. I have a question: is there a planned release tag for github.com/gofiber/fiber/v2 that includes this fix?

As of today, the latest v2 release is v2.52.13 (released April 25, 2026), which predates this merge (July 3, 2026). This means the fix for CVE-2026-45045 / GHSA-gcfq-8gqf-4876 is only available on the v2 branch HEAD but not in any tagged release that Go modules can resolve.

Why this matters for v2 consumers:

  1. Go modules require a tagged release to pull in the fix. Running go get github.com/gofiber/fiber/v2@latest still resolves to v2.52.13, which remains vulnerable.
  2. Dependabot / govulncheck / Trivy / Snyk continue to flag projects using github.com/gofiber/fiber/v2 as affected because the advisory's patched_versions field has no v2 entry. A tagged release would allow the advisory to be updated and automated scanners to clear the alert.
  3. Many production projects cannot pin to a commit hash due to internal policies or compliance requirements that mandate semver-tagged dependencies. Without a release, these teams are stuck between "known vulnerable" and "use an untagged commit."

Would it be possible to cut a v2.52.14 (or similar) patch release that includes this commit? This would unblock the entire v2 ecosystem from resolving the CVE through normal dependency update workflows.

Thank you!

@ReneWerner87

Copy link
Copy Markdown
Member

https://github.com/gofiber/fiber/releases/tag/v2.52.14

lima3w added a commit to lima3w/padduck that referenced this pull request Jul 16, 2026
Dependabot flagged CVE-worthy behavior in gofiber's BalancerForward proxy
helper: it used Header.Add() instead of Header.Set() when injecting
X-Real-IP, letting an attacker-supplied value survive alongside the real
client IP. padduck doesn't import gofiber/fiber/v2/middleware/proxy (only
logger and recover are vendored), so this was never reachable here, but
bumping to the patched release (which backports gofiber/fiber#4495) is
cheap and closes the Dependabot alert.

Also carries the govulncheck Makefile fix from the unmerged
fix/database-url-userinfo-encoding branch (checks Go version from
backend/ instead of the repo root, which has no go.mod) — needed here too
since this branch was cut from main before that PR merged.

Claude-Session: https://claude.ai/code/session_01W5iuFK1sBPceJfvaYnjAot
lima3w added a commit to lima3w/padduck that referenced this pull request Jul 16, 2026
Dependabot flagged CVE-worthy behavior in gofiber's BalancerForward proxy
helper: it used Header.Add() instead of Header.Set() when injecting
X-Real-IP, letting an attacker-supplied value survive alongside the real
client IP. padduck doesn't import gofiber/fiber/v2/middleware/proxy (only
logger and recover are vendored), so this was never reachable here, but
bumping to the patched release (which backports gofiber/fiber#4495) is
cheap and closes the Dependabot alert.

Also carries the govulncheck Makefile fix from the unmerged
fix/database-url-userinfo-encoding branch (checks Go version from
backend/ instead of the repo root, which has no go.mod) — needed here too
since this branch was cut from main before that PR merged.

Claude-Session: https://claude.ai/code/session_01W5iuFK1sBPceJfvaYnjAot
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants