
عرض Go محلي لإثبات المفهوم يوضح CVE-2026-72815، وهو خلل انتحال IP عبر X-Forwarded-For في go-chi/chi middleware.RealIP يتجاوز قوائم التحكم بالوصول المعتمدة على IP، مع مقارنة بالإصدار المُصلَّح v5.3.0.
middleware.RealIP انتحال IP PoCهذا المستودع هو إثبات مفهوم محلي (PoC) لثغرة انتحال IP CVE-2026-72815 (GHSA-3fxj-6jh8-hvhx) الموجودة في middleware.RealIP الخاص بـ go-chi/chi.
يقوم middleware RealIP المصاب بثغرة بالثقة غير المشروطة بالقيمة الأولى (الأقصى يسارًا) في X-Forwarded-For، ويستبدل بها قيمة http.Request.RemoteAddr. في التكوينات التي يمكن للعميل فيها تحديد X-Forwarded-For، قد يتمكن المهاجم من انتحال أي عنوان IP كمصدر، وتجاوز أو تلويث قوائم التحكم بالوصول (ACL) المعتمدة على IP، وحدود المعدل (rate limit)، وسجلات التدقيق.
يستخدم هذا PoC فقط httptest، ولا يقوم بأي اتصال بمضيفين خارجيين.
يُستخدم فقط للأغراض التعليمية والتحقق الأمني المصرح به. لا تستخدمه ضد بيئات الآخرين دون إذن.
github.com/go-chi/chi/v5middleware.RealIP>= 5.2.1, < 5.3.05.3.0عند وجود X-Forwarded-For، يقوم middleware.RealIP بأخذ القيمة الأولى المفصولة بفواصل وتعيينها في 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، تمت إضافة ClientIPFromHeader وClientIPFromXFF وClientIPFromXFFTrustedProxies وClientIPFromRemoteAddr كبدائل لـ RealIP.
تفترض حالة 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 القديم نفسه موجودًا لأغراض التوافق الخلفي. تمت إضافة ملاحظة deprecated إلى RealIP، ويُنصح بالانتقال إلى واجهات API الآمنة ClientIPFrom*.
لذلك، لا يكفي مجرد تحديث التبعية (dependency) إلى v5.3.0 والاستمرار في استخدام middleware.RealIP، بل يجب الانتقال إلى middleware ClientIPFrom* المناسب لتكوين الشبكة / reverse proxy الفعلي.
يتحقق هذا المستودع فقط مما يلي:
middleware.RealIP يعكس قيمة XFF اليسرى التي يتحكم بها المهاجم في RemoteAddrClientIPFromXFF() في v5.3.0 مع تكوين proxy مناسب، يمكن رفض نفس المدخلاتلا يقوم بأي فحص للشبكات الفعلية، أو طلبات لخدمات الآخرين، أو DoS، أو استمرارية (persistence).
middleware.RealIP إلى middleware ClientIPFrom* المناسب للبنية التحتية الفعلية