React2Shell: How I Would Handle a Critical RSC Vulnerability as a Full-Stack Developer
A practical Full-Stack developer article about React2Shell, the React Server Components vulnerability wave, and how I would detect, patch, verify, rotate secrets, and harden a real Next.js production app.
React2Shell: كيف أتعامل مع ثغرة خطيرة في React Server Components كمطوّر Full-Stack
مرحبًا، اسمي عمرو سمير، وأنا Full-Stack Web Developer.
ممكن نعم، وممكن لا: هل React2Shell تعتبر مشكلة Frontend؟
نعم، لأنها ظهرت في عالم React.
لكن في نفس الوقت لا، لأن الخطر الحقيقي لم يكن زر لا يعمل، أو مشكلة hydration، أو bug في الواجهة. الخطر كان في تنفيذ كود على السيرفر من خلال React Server Components. وهذا يعني أن الموضوع قد يصل إلى الكود المصدري، المتغيرات السرية، صلاحيات الكلاود، اللوجات، الحاويات، وطريقة النشر نفسها.
وهذا بالضبط السبب الذي يجعلني أتعامل مع تطوير الويب الحديث كنظام كامل، وليس مجرد واجهة وشوية APIs. عندما نستخدم Next.js App Router و React Server Components و Server Actions و API routes، فنحن لا نكتب UI فقط. نحن نشغّل جزءًا من التطبيق على السيرفر، وأي جزء يعمل على السيرفر يحتاج انضباطًا أمنيًا حقيقيًا.
هذا المقال ليس شرحًا لطريقة استغلال الثغرة. لن أضع payloads أو خطوات استغلال. ما أريد توضيحه هو كيف أفهم الثغرة، كيف أحدد الأولوية، كيف أصلحها، كيف أتحقق من الإصلاح، وكيف أجعل المشروع أقوى بعد ذلك.
ما هي React2Shell؟
React2Shell هو الاسم الشائع للثغرة CVE-2025-55182، وهي ثغرة خطيرة في React Server Components.
بشكل مختصر:
- أثّرت على حزم مرتبطة بـ React Server Components.
- كانت pre-authentication، أي لا تحتاج تسجيل دخول.
- قد تسمح بتنفيذ كود عن بُعد في البيئات المتأثرة.
- تم تصنيفها بدرجة خطورة عالية جدًا.
- أثّرت على بعض التطبيقات التي تستخدم Frameworks تعتمد على RSC، مثل بعض تطبيقات Next.js App Router.
- لم يكن التصحيح الأول كافيًا للتوقف تمامًا، لأن موجة لاحقة من مشاكل RSC ظهرت بعدها.
النقطة الأخيرة مهمة جدًا.
كثير من المطورين يرون advisory واحد، يعملون upgrade مرة واحدة، ثم ينسون الموضوع. مع هذه الثغرة، هذا التفكير كان خطرًا. بعد RCE الأولى ظهرت مشاكل أخرى مثل source exposure و denial of service، وبعض الإصلاحات القديمة أصبحت غير كافية بعد التحديثات اللاحقة.
لذلك السؤال الصحيح ليس:
هل قمت بتصحيح أول CVE؟
السؤال الأفضل هو:
هل وصلت إلى آخر إصدار آمن فعليًا، وهل تأكدت أن الإصدار الآمن هو الذي يعمل في production؟
لماذا هذا مهم بالنسبة لي كمطوّر Full-Stack؟
عندما أبني مشروع Portfolio، أو SaaS dashboard، أو admin panel، أو متجر إلكتروني، أو منصة لعميل، غالبًا أفكر في:
- واجهة نظيفة
- أداء جيد
- Authentication
- تنظيم الـ API
- تصميم قاعدة البيانات
- النشر
- SEO
- تجربة المستخدم
لكن React2Shell تذكرني أن الأمان يجب أن يكون بجانب كل هذه الأشياء.
إذا كان تطبيق Next.js يستخدم App Router وميزات React التي تعمل على السيرفر، فالتطبيق ليس “Frontend فقط”. يوجد سطح هجوم server-side. ووجود ثغرة في هذه الطبقة قد يؤثر على التطبيق بالكامل.
بالنسبة لي، الدرس الأساسي هو:
إطار عمل Frontend حديث يمكن أن ينتج مخاطر Backend حقيقية.
لذلك أتعامل مع هذا النوع من الثغرات كحادث إنتاجي، وليس كتحديث dependency عادي.
أول رد فعل: أتعامل معها كـ P0 إذا كان التطبيق Public
إذا اكتشفت أن أحد تطبيقاتي قد يكون متأثرًا، لا أبدأ بإعادة تصميم النظام أو قراءة نقاشات عشوائية.
أبدأ بثلاثة أسئلة:
- هل التطبيق متاح على الإنترنت؟
- هل يستخدم Next.js App Router أو أي إعداد يدعم RSC؟
- ما هي الإصدارات الحقيقية المثبتة والمنشورة؟
إذا كان التطبيق public والإصدارات متأثرة، فبالنسبة لي هذا P0.
ليس “السبرنت القادم”.
ليس “عندما يكون لدي وقت”.
ليس “بعد هذه الميزة”.
ثغرة server-side خطيرة ولا تحتاج تسجيل دخول يجب التعامل معها فورًا، خصوصًا إذا كان هناك استغلال فعلي لها في العالم الحقيقي.
كيف أتحقق إذا كان المشروع متأثرًا؟
أول خطأ أريد تجنبه هو الاعتماد على package.json فقط.
ملف package.json يخبرني بما طلبته. أما lockfile و dependency tree فيخبراني بما تم تثبيته فعليًا.
لذلك أبدأ بفحص الشجرة:
npm ls next react react-dom react-server-dom-webpack react-server-dom-parcel react-server-dom-turbopack --all
ثم أسأل npm لماذا توجد الحزمة:
npm explain react-server-dom-webpack
npm explain react-server-dom-parcel
npm explain react-server-dom-turbopack
إذا كان المشروع يستخدم pnpm:
pnpm why react-server-dom-webpack
pnpm why react-server-dom-parcel
pnpm why react-server-dom-turbopack
وإذا كان يستخدم Yarn:
yarn why react-server-dom-webpack
yarn why react-server-dom-parcel
yarn why react-server-dom-turbopack
ثم أتحقق هل المشروع يستخدم App Router فعلًا:
app/
app/page.tsx
app/layout.tsx
app/api/
وإذا كان المشروع monorepo، لا أفحص root فقط. أفحص كل app يتم نشره.
قاعدة الإصدارات التي أتبعها
بالنسبة إلى React وحزم RSC، لا أتوقف عند أول patch ظهر في أول advisory. لأن المشاكل اللاحقة جعلت الحد الآمن العملي يتحرك مرة أخرى، أستهدف أحدث إصدار آمن في نفس release line.
إذا كان المشروع يستخدم React Server Components packages مباشرة، فالحد الآمن الذي أستهدفه يكون مثل:
react@19.0.4
react-dom@19.0.4
react-server-dom-webpack@19.0.4
أو:
react@19.1.5
react-dom@19.1.5
react-server-dom-webpack@19.1.5
أو:
react@19.2.4
react-dom@19.2.4
react-server-dom-webpack@19.2.4
وإذا كان المشروع يستخدم react-server-dom-parcel أو react-server-dom-turbopack، أحرص أن تكون على نفس الخط الآمن أيضًا.
أما في Next.js، فأختار الإصدار الآمن المناسب لخط المشروع الحالي، مثل:
npm install next@14.2.35
npm install next@15.0.8
npm install next@15.1.12
npm install next@15.2.9
npm install next@15.3.9
npm install next@15.4.11
npm install next@15.5.10
npm install next@16.0.11
npm install next@16.1.5
في الواقع العملي، لا أضع كل هذه الأوامر عشوائيًا. أختار الإصدار المناسب لخط Next.js الذي يعمل عليه المشروع، ثم أختبره وأنشره.
طريقة المعالجة التي أتبعها
هذه هي الخطوات التي أتبعها في مشروع حقيقي.
1. إنشاء branch أمني
git checkout -b fix/react2shell-rsc-security
أريد الإصلاح أن يكون واضحًا، قابلًا للمراجعة، وسهل النشر.
2. تسجيل الإصدارات الحالية
node -v
npm -v
npx next --version
npm ls next react react-dom react-server-dom-webpack react-server-dom-parcel react-server-dom-turbopack --all
هذا يعطيني صورة قبل وبعد.
3. ترقية الحزم المناسبة
إذا كنت أستخدم Next.js، أبدأ غالبًا بترقية Next.js لأن Next يتحكم في جزء كبير من سلسلة RSC dependencies.
مثال:
npm install next@15.5.10
ثم أنفذ clean install:
rm -rf node_modules package-lock.json
npm install
في مشروع production، أتعامل مع هذه الخطوة بحذر. لا أريد ترقيات عشوائية غير مرتبطة بالإصلاح. في بعض الفرق، أفضل تحديث lockfile بشكل أدق بدل حذفها بالكامل.
4. البناء والاختبار
npm run lint
npm run build
npm test
وإذا كان المشروع يحتوي على E2E tests:
npm run test:e2e
5. فحص التبعيات
npm audit --audit-level=high
وإذا كان المشروع يستخدم Trivy:
trivy fs --severity HIGH,CRITICAL --exit-code 1 .
6. إعادة بناء صورة النشر
هذا مهم لأن Docker layers القديمة قد تخفي dependencies قديمة.
docker build --no-cache -t my-app:react2shell-fixed .
7. نشر كل البيئات المتأثرة
لا أصلح production فقط.
أفحص:
- Production
- Staging
- Preview deployments
- Worker services
- Cron jobs
- Self-hosted copies
- Internal dashboards
- Demo environments
الثغرات الأمنية غالبًا تبقى بسبب بيئة منسية تعمل بكود قديم.
التحقق بعد النشر
بعد النشر، أتحقق من artifact الذي يعمل فعليًا.
ليس جهازي المحلي. وليس GitHub فقط. بل البيئة التي تعمل في production.
أشغّل:
npx next --version
npm ls next react react-dom react-server-dom-webpack react-server-dom-parcel react-server-dom-turbopack --all
ثم أراجع اللوجات والـ metrics خلال فترة التعرض المحتملة.
الأشياء التي أراجعها:
- أخطاء 500 غير طبيعية
- طلبات غريبة على App Router أو Server Function endpoints
- ارتفاع CPU بشكل مفاجئ
- إعادة تشغيل containers
- OOM kills
- Outbound network traffic غير معروف
- عمليات shell غير متوقعة
- كتابة ملفات غريبة
- نشاط authentication مشبوه
- وصول غير متوقع إلى secrets
هنا الفرق بين patching و incident response. إذا كان التطبيق public ومتأثرًا، فالتصحيح هو الخطوة الأولى. التحقيق هو الخطوة الثانية.
هل يجب تدوير الأسرار؟
إذا كان التطبيق متاحًا للعامة خلال فترة الضعف، فسأفكر بجدية في تدوير الأسرار.
هذا يشمل:
- بيانات اتصال قاعدة البيانات
- API keys
- مفاتيح مزودي الدفع
- Cloud access tokens
- Webhook secrets
- JWT signing secrets
- OAuth client secrets
- CI/CD deployment tokens
- مفاتيح object storage
- Internal service tokens
أعرف أن تدوير الأسرار مزعج. وقد يكسر أشياء إذا تم بدون تنظيم. لكن مع احتمال server-side remote code execution، لا أحب افتراض أن الأسرار بقيت آمنة.
الترتيب الذي أتبعه:
- تدوير الأسرار الأعلى خطورة أولًا.
- إعادة النشر بمتغيرات البيئة الجديدة.
- إلغاء المفاتيح القديمة.
- مراقبة اللوجات بعد التغيير.
- توثيق ما تم تغييره.
WAF مفيد، لكنه ليس الإصلاح النهائي
Web Application Firewall يمكن أن يساعد في تقليل التعرض. بعض منصات الاستضافة ومزودي الكلاود يضيفون قواعد مؤقتة وقت الثغرات الكبيرة.
أنا أرى WAF كطبقة دفاع إضافية ممتازة، خصوصًا أثناء وقت الطوارئ.
لكن لا أعتبره الحل النهائي.
في هذه الحالة، الحل الصحيح هو:
- ترقية الحزم المتأثرة.
- إعادة البناء والنشر.
- التأكد من الإصدارات التي تعمل فعليًا.
- فحص فترة التعرض.
- تدوير الأسرار إذا لزم الأمر.
- إضافة فحوصات CI حتى لا تعود الإصدارات الضعيفة مرة أخرى.
WAF مثل حزام الأمان. أما patch فهو إصلاح الفرامل.
Guardrails في CI/CD بعد الإصلاح
بعد التصحيح العاجل، أريد أن أجعل تكرار المشكلة أصعب.
Dependabot
أفعّل Dependabot لتبعيات npm:
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
groups:
next-react-security:
patterns:
- "next"
- "react"
- "react-dom"
- "react-server-dom-*"
Security workflow
أبني workflow بسيط في GitHub Actions ينفذ:
npm ci
npm audit --audit-level=high
npm run build
npm test
وإذا كنت أستخدم Trivy:
trivy fs --severity HIGH,CRITICAL --exit-code 1 .
وفي مستودعات production، أفضل تثبيت third-party GitHub Actions باستخدام full commit SHA بدل الاعتماد على tags متغيرة. Supply chain security جزء مهم من القصة هنا.
Checklist سريع للحادث
هذا هو الـ checklist الذي أحتفظ به لمشكلة مثل هذه:
- التأكد هل التطبيق يستخدم App Router أو RSC.
- فحص dependency tree الفعلية.
- تحديد كل البيئات المنشورة.
- الترقية إلى آخر إصدار آمن مناسب للخط الحالي.
- إعادة البناء من clean install.
- تشغيل الاختبارات والفحوصات الأمنية.
- النشر لكل البيئات المتأثرة.
- التحقق من runtime versions بعد النشر.
- مراجعة اللوجات والـ telemetry.
- تدوير الأسرار إذا كان التطبيق exposed.
- إضافة CI checks لمنع عودة المشكلة.
- كتابة ملاحظة post-incident مختصرة.
النقطة الأخيرة مهمة جدًا. حتى لو كان المشروع فرديًا، أحب كتابة ملاحظة قصيرة:
- ماذا حدث؟
- هل كنت متأثرًا؟
- ماذا قمت بترقيته؟
- متى تم النشر؟
- هل تم تدوير الأسرار؟
- ما الذي سيمنع تكرار المشكلة؟
الهندسة الجيدة ليست كتابة كود فقط. هي أيضًا ترك أثر واضح يفهمه الشخص الذي سيأتي بعدك، حتى لو كان هذا الشخص هو أنت بعد شهرين.
طريقة التفكير طويلة المدى
React2Shell أوضحت شيئًا مهمًا: الحدود بين Frontend و Backend أصبحت أقل وضوحًا.
في التطبيقات الحديثة:
- بعض المكونات تعمل على السيرفر.
- Server Functions يمكن استدعاؤها من العميل.
- Frameworks تخفي تعقيد البنية التحتية.
- Build tools تولد server bundles.
- منصات الاستضافة تنشر preview deployments تلقائيًا.
- Environment variables قد تصبح أقرب إلى الكود مما نعتقد.
لذلك يجب أن أفكر كمهندس Full-Stack من البداية.
في مشروع Next.js جاد، سأركز على:
- تحديث Next.js و React باستمرار.
- عدم وضع الأسرار مباشرة داخل الكود.
- استخدام environment variables و secret managers بشكل صحيح.
- تقليل صلاحيات runtime.
- تطبيق least privilege على cloud credentials.
- مراقبة outbound traffic من containers.
- تسجيل الأحداث الأمنية المهمة.
- تشغيل dependency scans داخل CI.
- مراجعة preview deployments.
- استخدام WAF كطبقة دفاع إضافية.
- وجود rollback plan لا يعيد كودًا ضعيفًا.
ما الذي لن أفعله؟
لن أفعل الآتي:
- نسخ payloads من منشورات عشوائية.
- تشغيل أدوات scanner مجهولة على production.
- افتراض أن المشروع آمن فقط لأنه React.
- الثقة في
package.jsonبدون فحص lockfile. - تصحيح production ونسيان staging.
- ترك preview deployments مكشوفة.
- الاحتفاظ بالأسرار القديمة بعد احتمال التعرض.
- الاعتماد على WAF فقط.
- الرجوع إلى build قديم يحتوي على الثغرة.
- التعامل معها كأنها “مشكلة Frontend فقط”.
الحوادث الأمنية مرهقة بما يكفي. لا أريد جعلها أسوأ بتصرفات سريعة وغير محسوبة.
الخلاصة
React2Shell من الثغرات التي تغيّر طريقة نظرتك للـ stack.
بالنسبة لي، الدرس الكبير ليس فقط “حدّث React”. الدرس الحقيقي هو أن أطر العمل الحديثة تحتاج عادات تشغيل وأمان حديثة أيضًا.
إذا كنت أبني باستخدام Next.js App Router و React Server Components، يجب أن أمتلك الصورة الكاملة:
- Dependencies
- Lockfiles
- Runtime versions
- Secrets
- Logs
- CI/CD
- Deployment environments
- Rollback strategy
- Security monitoring
هذا لا يعني الخوف من React أو Next.js. بالعكس، ما زلت أحب تجربة التطوير فيهما جدًا. لكن هذا يعني احترام القوة التي أصبحت هذه الأدوات تمتلكها على السيرفر.
المطوّر الجيد لا يسأل فقط:
هل الواجهة تعمل؟
بل يسأل أيضًا:
ماذا يحدث إذا أصبحت إحدى التبعيات خطيرة غدًا، وكم بسرعة أستطيع إصلاحها بأمان؟
هذا هو التفكير الذي أريد الاستمرار في البناء به.
منشورات مقترحة
مشاريع ذات صلة

E-techPay هو منصة تجارة إلكترونية كاملة تجعل التسوق عبر الإنترنت سهلًا وآمنًا. إنه سريع، موثوق، ومصمم لتقديم أفضل تجربة تسوق.
