
PoC Go local démontrant CVE-2026-72815, une faille d'usurpation d'IP via X-Forwarded-For dans le middleware RealIP de go-chi/chi qui contourne les ACL basées sur l'IP, avec une comparaison corrigée en v5.3.0.
middleware.RealIP de go-chi/chiCe dépôt est une preuve de concept (PoC) locale de la vulnérabilité d'usurpation d'IP CVE-2026-72815 (GHSA-3fxj-6jh8-hvhx) présente dans middleware.RealIP de go-chi/chi.
Le middleware RealIP vulnérable fait confiance inconditionnellement à la première valeur (la plus à gauche) de X-Forwarded-For et écrase http.Request.RemoteAddr avec cette valeur. Dans une configuration où le client peut spécifier X-Forwarded-For, un attaquant peut usurper une adresse IP arbitraire comme source, ce qui peut permettre de contourner ou de polluer les ACL basées sur l'IP, les limites de débit, les journaux d'audit, etc.
Cette PoC utilise uniquement httptest et n'effectue aucune communication vers des hôtes externes.
À utiliser uniquement à des fins éducatives et pour des vérifications de sécurité autorisées. Ne l'utilisez pas sans autorisation contre des environnements tiers.
github.com/go-chi/chi/v5middleware.RealIP>= 5.2.1, < 5.3.05.3.0Lorsque X-Forwarded-For est présent, middleware.RealIP récupère la première valeur séparée par des virgules et la définit dans RemoteAddr.
Conceptuellement, le traitement est le suivant.
if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
ip, _, _ = strings.Cut(xff, ",")
}
r.RemoteAddr = ip
Normalement, un reverse proxy ajoute l'IP source réelle à la fin du X-Forwarded-For existant. Par conséquent, si un attaquant peut spécifier au préalable une valeur comme la suivante, la valeur la plus à gauche n'est pas fiable.
X-Forwarded-For: 127.0.0.1, 203.0.113.50
Le RealIP vulnérable adopte 127.0.0.1 comme IP du client.
cd vulnerable
GOWORK=off go run .
La PoC suppose que le client réel est 203.0.113.50 et que l'IP autorisée en tant qu'administrateur est 127.0.0.1.
Une requête normale renvoie HTTP 403, mais une requête avec l'en-tête suivant voit RealIP réécrire RemoteAddr en 127.0.0.1, ce qui donne HTTP 200.
X-Forwarded-For: 127.0.0.1, 203.0.113.50
Sortie principale attendue :
=== CVE-2026-72815 vulnerable case ===
[*] go-chi/chi version: v5.2.1
[*] normal request status: 403
[*] spoofed request status: 200
[!] VULNERABLE: attacker-controlled X-Forwarded-For bypassed the IP ACL.
cd fixed
GOWORK=off go run .
Dans v5.3.0, ClientIPFromHeader, ClientIPFromXFF, ClientIPFromXFFTrustedProxies et ClientIPFromRemoteAddr ont été ajoutés comme alternatives à RealIP.
Le cas corrigé de cette PoC utilise ClientIPFromXFF() en supposant une configuration où « un proxy de confiance se trouve juste devant le serveur et ce proxy ajoute l'IP réelle du client à la fin du XFF ». Même si le même en-tête usurpé est envoyé, c'est le 203.0.113.50 à l'extrémité droite qui est adopté, ce qui empêche de franchir l'ACL.
Sortie principale attendue :
=== CVE-2026-72815 safe replacement case ===
[*] go-chi/chi version: v5.3.0
[*] normal request status: 403
[*] spoofed request status: 403
[+] SAFE: the spoofed leftmost X-Forwarded-For value did not bypass the IP ACL.
bash scripts/run-version-matrix.sh
Dans v5.3.0 également, le comportement de l'ancien middleware.RealIP est conservé tel quel pour des raisons de compatibilité ascendante. Une note de dépréciation a été ajoutée à RealIP, et la migration vers les API sûres ClientIPFrom* est recommandée.
Par conséquent, il ne suffit pas de simplement mettre à jour la dépendance vers v5.3.0 en continuant à utiliser middleware.RealIP ; il est nécessaire de migrer vers le middleware ClientIPFrom* adapté à la configuration réseau / reverse proxy réelle.
Ce dépôt vérifie uniquement les points suivants.
middleware.RealIP reflète dans RemoteAddr la valeur XFF la plus à gauche contrôlée par l'attaquantClientIPFromXFF() de v5.3.0 avec une configuration proxy appropriée, la même entrée peut être rejetéeAucun scan de réseau réel, requête vers des services tiers, DoS, persistance, etc. n'est effectué.
middleware.RealIP vers le middleware ClientIPFrom* adapté à l'infrastructure réelle