ثغرة Next.js CVE-2026-27979: الـ PPR بيفضّي الذاكرة، تتصرف إزاي
لو بتشغّل Next.js بين 16.0.1 و 16.1.6 مع Partial Prerendering، السيرفر بتاعك ممكن يقع من طلب POST واحد. ثغرة CVE-2026-27979 بتخلي الذاكرة تـ grow من غير حد لحد ما الـ process يموت بـ OOM. الإصلاح بياخد أقل من ساعة، بس لازم يتعمل النهارده مش بكرة.
المشكلة باختصار
Vercel أعلنت في منتصف أبريل 2026 عن ثغرة Denial of Service بتصيب الإصدارات من 16.0.1 لحد 16.1.6. الثغرة في الـ Partial Prerendering (PPR) اللي Next.js بتدفعها كـ feature أساسية من Next 16. المهاجم بيبعت طلب POST فيه header اسمه next-resume: 1 مع body كبير، والسيرفر بيـ buffer الطلب كامل في الذاكرة من غير ما يطبّق حد maxPostponedStateSize. كام طلب متوازي = الـ instance راح.
ليه ده بيحصل أصلًا
فكرة الـ PPR إن الصفحة فيها shell ثابت + أجزاء ديناميكية بتتبني على الـ fly. لما الـ client بيطلب استكمال جزء ديناميكي، بيبعت طلب ومعاه state مشفّر علشان السيرفر يكمّل الرندر من نفس النقطة. Next.js عندها إعداد اسمه maxPostponedStateSize مفروض يرفض أي state أكبر من الحد. المشكلة إن المسار اللي بيستقبل next-resume: 1 ما بيتحقّقش من الحد ده قبل ما يبدأ يخزّن الطلب.
النتيجة بالظبط: body بـ 500 ميجا بيتحطّ في الذاكرة قبل ما يتفحص. الـ CWE هنا 770 — Allocation of Resources Without Limits. تصنيف الـ CVSS بيحطها كـ DoS عن بُعد من غير authentication، وده اللي بيخلّيها خطرة حتى لو التطبيق بتاعك مش banking.
الحل الرسمي في 4 خطوات
- افتح
package.jsonواتأكد من إصدارnext. أي رقم من 16.0.1 لـ 16.1.6 = مكشوف. - رقّي لـ 16.1.7 أو أحدث:
npm install next@^16.1.7(أوpnpm update next). - نفّذ
npm run buildمحليًا وشغّل الـ integration tests قبل ما تـ deploy. - بعد الـ deploy، ابعت طلب الاختبار اللي تحت علشان تتأكد إن الثغرة قفلت فعلًا.
# اختبار بعد الترقية — المفروض يرجع 413 أو 400، مش 200 ولا timeout
curl -X POST https://your-app.com/any-ppr-route \
-H "next-resume: 1" \
-H "Content-Type: text/plain" \
--data-binary @<(head -c 50M /dev/urandom)
# راقب الـ memory في نفس اللحظة
ps -o pid,rss,cmd -C nodeلو مقدرش ترقّي فورًا
الحل المؤقت: امنع الـ header عند الـ edge قبل ما يوصل للتطبيق. لو عندك Cloudflare، اعمل WAF rule: