Public mode

No access to your tenant or devices. Every item links to its source. What this means

Some sources or documents need attention: 261/275 feeds/APIs · 469/469 docs · 9/9 advisories · checked 19:07 UTC Customize Public modeDiscuss ChangeIntel on Discord

chi's RealIP Middleware allows IP spoofing via unvalidated X-Forwarded-For header

Exact source revision recorded 24 Oct 2026 13:19:41 UTC. It does not establish the source's current position. Latest evidence.

osv · GHSA-rjr7-jggh-pgcp

Published

### Summary realip middleware in go-chi/chi trusts headers like x-forwarded-for without checking them, so attackers can fake their ip and bypass rate limits or access controls ### Details the vuln is in middleware/realip.go , the realIP() function pulls IPs straight from client headers and replaces r.RemoteAddr without checking if the request came from a trusted proxy ```go func realIP(r *http.Request) string { var ip string if tcip := r.Header.Get(trueClientIP); tcip != "" { ip = tcip // controlled by attacker } else if xrip := r.Header.Get(xRealIP); xrip != "" { ip = xrip // controlled by attacker } else if xff := r.Header.Get(xForwardedFor); xff != "" { ip, _, _ = strings.Cut(xff, ",") // controlled by attacker } // ... return ip } ``` no trusted proxy cidr check in place, any client can send these headers ### PoC create a server with chi and use realip middleware ```go package main import ( "fmt" "net/http" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" ) func main() { r := chi.NewRouter() r.Use(middleware.RealIP) r.Get("/admin", func(w http.ResponseWriter, r *http.Request) { // ip-based access control got bypassed if r.RemoteAddr == "127.0.0.1" { w.Write([]byte("SECRET ADMIN DATA")) return } http.Error(w, "Forbidden", 403) }) http.ListenAndServe(":8080", r) } ``` spoofed the ip to bypass access control ```bash curl -H "X-Forwarded-For: 127.0.0.1" http://localhost:8080/admin ``` ### Impact - ip-based access control bypass lets attackers reach restricted endpoints - rate limiting bypass lets attackers avoid limits by rotating spoofed ips - audit logs show fake ips picked by attacker instead of real ones - attackers can get around geo ip restrictions ## Remediation Recommendation validate proxy cidr first before trusting forwarded ip headers ```go // add your reverse proxy ip addresses here var trustedProxies = []net.IPNet{ {IP: net.ParseIP("10.0.0.0"), Mask: net.CIDRMask(8, 32)}, {IP: net.ParseIP("172.16.0.0"), Mask: net.CIDRMask(12, 32)}, {IP: net.ParseIP("192.168.0.0"), Mask: net.CIDRMask(16, 32)}, } func isTrustedProxy(ip net.IP) bool { for _, cidr := range trustedProxies { if cidr.Contains(ip) { return true } } return false } ```

Source published
25 Jun 2026 18:19:15 UTC
Source modified
10 Sep 2026 03:50:50 UTC
Observed here
24 Oct 2026 13:19:41 UTC
Source terms
GitHub Advisory Database · CC-BY-4.0

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: osv · GitHub Advisory Database · CC-BY-4.0. Source text is retained; field grouping and change labels are provided by ChangeIntel.

CVSS_V4 · CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N/E:P

Publisher rating · HIGH

ChangeIntel

An IT change radar: releases, security, known issues, retirements, documentation changes, and service status from public sources. Every item links to supporting evidence; dates and statuses can change after they are read.

Sources read 10 Nov 19:07 UTC · 261 of 275 readable · 260 fully read · documentation 469/469 current