---
id: CVE-2026-45045
title: GoFiber Vulnerable to X-Real-IP Spoofing via Header.Add() in BalancerForward
summary: GoFiber Vulnerable to X-Real-IP Spoofing via Header.Add() in BalancerForward
severity: medium
cvss: 5.3
cwe:
  - CWE-290
vendor: gofiber
product: github.com/gofiber/fiber/v3
ecosystem: go
affected:
  - github.com/gofiber/fiber/v3 <= 3.2.0
  - github.com/gofiber/fiber/v2 <= 2.52.13
patched:
  - github.com/gofiber/fiber/v3 3.3.0
published: '2026-07-02'
updated: '2026-07-02'
source: GHSA
sourceUrl: 'https://github.com/advisories/GHSA-gcfq-8gqf-4876'
references:
  - url: 'https://github.com/gofiber/fiber/security/advisories/GHSA-gcfq-8gqf-4876'
  - url: 'https://github.com/advisories/GHSA-gcfq-8gqf-4876'
tags:
  - ghsa
  - go
ingestedAt: '2026-07-02T14:37:13.947Z'
epss: 0.00463
epssPercentile: 0.3937
---

## Overview

## Summary

The `BalancerForward` proxy helper in GoFiber uses `Header.Add()` instead of `Header.Set()` when injecting the `X-Real-IP` header. This appends the real client IP as a second header value rather than replacing any attacker-supplied value. Upstream servers that read the first `X-Real-IP` header (nginx, Express, most HTTP servers) use the attacker's spoofed IP for logging, rate limiting, and access control.

## Vulnerable Code

**File:** `middleware/proxy/proxy.go`, lines 270-285

```go
func BalancerForward(servers []string, clients ...*fasthttp.Client) fiber.Handler {
    r := &roundrobin{
        current: 0,
        pool:    servers,
    }
    return func(c fiber.Ctx) error {
        server := r.get()
        if !strings.HasPrefix(server, "http") {
            server = "http://" + server
        }
        c.Request().Header.Add("X-Real-IP", c.IP())   // line 282: Add, not Set
        return Do(c, server+c.OriginalURL(), clients...)
    }
}
```

## Data Flow

1. Attacker sends request with `X-Real-IP: 10.0.0.1` (spoofed internal IP)
2. `BalancerForward` handler executes at line 282
3. `c.Request().Header.Add("X-Real-IP", c.IP())` APPENDS the real IP as a second header
4. Upstream server receives: `X-Real-IP: 10.0.0.1` AND `X-Real-IP: <real-attacker-ip>`
5. Most HTTP servers (nginx, Node.js, Apache) read the FIRST value
6. Upstream uses `10.0.0.1` for all IP-dependent logic

## Impact

- **Rate limit bypass:** IP-based rate limiting at the upstream uses the spoofed IP, allowing unlimited requests
- **IP ACL bypass:** Internal IP allowlists (e.g., admin panels restricted to `10.0.0.0/8`) can be bypassed
- **Audit log poisoning:** Security logs record the spoofed IP, making incident investigation unreliable
- **Geolocation bypass:** IP-based geofencing or region restrictions are circumvented

## Fix

Replace `Header.Add()` with `Header.Set()` at line 282:

```go
c.Request().Header.Set("X-Real-IP", c.IP())
```

`Header.Set()` replaces any existing header value, ensuring only the real client IP is forwarded.

## Affected packages

- `github.com/gofiber/fiber/v3 <= 3.2.0`
- `github.com/gofiber/fiber/v2 <= 2.52.13`

## Remediation

Upgrade to a patched release:

- `github.com/gofiber/fiber/v3 3.3.0`
