
Локальный PoC на Go, демонстрирующий CVE-2026-72815 — уязвимость подмены IP через X-Forwarded-For в middleware go-chi/chi middleware.RealIP, позволяющую обойти ACL на основе IP, со сравнением с исправленной версией v5.3.0.
middleware.RealIP IP Spoofing PoCЭтот репозиторий представляет собой локальный Proof of Concept (PoC) для уязвимости IP spoofing CVE-2026-72815 (GHSA-3fxj-6jh8-hvhx), существующей в middleware.RealIP из go-chi/chi.
Уязвимое middleware RealIP безусловно доверяет первому (крайнему левому) значению в X-Forwarded-For и перезаписывает им http.Request.RemoteAddr. В конфигурациях, где клиент может задавать X-Forwarded-For, злоумышленник может подменить произвольный IP-адрес в качестве источника запроса, что позволяет обходить или загрязнять IP-based ACL, rate limit, журналы аудита и т. д.
Данный PoC использует только httptest и не выполняет соединений с внешними хостами.
Используйте только в образовательных целях и для разрешённой проверки безопасности. Не используйте без разрешения против сред третьих лиц.
github.com/go-chi/chi/v5middleware.RealIP>= 5.2.1, < 5.3.05.3.0middleware.RealIP при наличии X-Forwarded-For берёт первое значение, разделённое запятой, и устанавливает его в RemoteAddr.
Концептуально это выглядит так:
if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
ip, _, _ = strings.Cut(xff, ",")
}
r.RemoteAddr = ip
Обычно reverse proxy добавляет реальный IP-адрес источника в конец существующего X-Forwarded-For. Поэтому если злоумышленник может заранее указать такое значение, крайнее левое значение доверять нельзя:
X-Forwarded-For: 127.0.0.1, 203.0.113.50
Уязвимый RealIP примет 127.0.0.1 в качестве IP-адреса клиента.
cd vulnerable
GOWORK=off go run .
PoC предполагает, что реальный клиент имеет адрес 203.0.113.50, а IP-адрес, разрешённый для администратора, — 127.0.0.1.
Обычный запрос вернёт HTTP 403, но запрос со следующим заголовком приведёт к тому, что RealIP перезапишет RemoteAddr на 127.0.0.1, и ответ будет HTTP 200.
X-Forwarded-For: 127.0.0.1, 203.0.113.50
Ожидаемый основной вывод:
=== 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 .
В v5.3.0 в качестве замены RealIP добавлены ClientIPFromHeader, ClientIPFromXFF, ClientIPFromXFFTrustedProxies, ClientIPFromRemoteAddr.
Fixed case в этом PoC предполагает конфигурацию, в которой «непосредственно перед сервером находится один доверенный proxy, и этот proxy добавляет реальный IP-адрес клиента в конец XFF», и использует ClientIPFromXFF(). Даже при отправке того же поддельного заголовка будет принято крайнее правое значение 203.0.113.50, поэтому обойти ACL не удастся.
Ожидаемый основной вывод:
=== 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
Даже в v5.3.0 само поведение старого middleware.RealIP сохранено для обратной совместимости. В RealIP добавлено примечание о deprecated, и рекомендуется переход на безопасные API ClientIPFrom*.
Следовательно, недостаточно просто обновить зависимость до v5.3.0 и продолжать использовать middleware.RealIP — необходимо перейти на middleware ClientIPFrom*, соответствующий реальной конфигурации сети / reverse proxy.
Данный репозиторий проверяет только следующее.
middleware.RealIP отражает контролируемое злоумышленником крайнее левое значение XFF в RemoteAddrClientIPFromXFF() из v5.3.0 в подходящей конфигурации proxy тот же ввод будет отклонёнСканирование реальных сетей, запросы к сервисам третьих лиц, DoS, закрепление в системе и т. п. не выполняются.
middleware.RealIP на middleware ClientIPFrom*, соответствующий реальной инфраструктуре