باگ DoS در Server Actionهای ریاکت با یه درخواست ۹۰۰ کیلوبایتی
خلاصهٔ کاملتر
ریاکت جدید بهت اجازه میده یه فرم رو مستقیم به یه تابع سمت سرور وصل کنی که بهش server action میگن. قبل از اینکه این تابع اجرا بشه، ریاکت باید درخواست HTTP خام رو بگیره و دادههای فرم رو ازش بازسازی کنه. نویسنده میگه همین کد بازسازی دقیقاً جاییه که ارزش گشتن داره، چون روی هر فراخوانی اجرا میشه و کل ورودیش دست فرستندهست.
تو فرمت ریاکت، یه فیلد میتونه به یه فیلد دیگه اشاره کنه. یکی از این اشارهگرها $K هست، یعنی «اینجا یه فرم تودرتو داریم». مشکل اینجاست که ریاکت برای هر $K یه بار کل لیست فیلدهای درخواست رو از اول تا آخر میگشت. نه تعداد اشارهگرها محدودیت داشت، نه تعداد فیلدها. با ۱۰ هزار اشارهگر و ۱۰ هزار فیلد، میشه ۱۰۰ میلیون مقایسهٔ رشته پشت سر هم.
چون Node.js همهٔ درخواستها رو روی یه thread پردازش میکنه، تا این حلقه تموم نشه هیچ کاربر دیگهای جواب نمیگیره. ریاکت دو تا محدودیت اندازه کنار همین کد داشت، ولی هیچکدوم جلوشو نمیگرفت: یکی فقط عمق آرایههای تودرتو رو چک میکرد و اون یکی تعداد آرگومانهای action رو. نویسنده توضیح میده که با گذاشتن لیست بزرگ اشارهگرها یه سطح پایینتر از جایی که اون محدودیت نگاه میکنه، چک دوم دور زده میشد.
بدتر اینکه بازسازی فرم قبل از هر چک امنیتی اجرا میشه: نه لاگین، نه توکن CSRF، نه چک origin. تنها چیزی که لازمه action ID هست، یعنی هشی که اسم تابع سرور رو مشخص میکنه، و اونم تو HTML صفحه و فایلهای JS سمت کلاینت پیداست. طبق تست نویسنده، روی لپتاپ یه درخواست سرور رو حدود ۴ ثانیه قفل کرد. تو یه محیط شبیه پروداکشن حدود ۱۰ ثانیه طول کشید و سه درخواست پشت سر هم باعث شد load balancer سرور رو مرده حساب کنه و به بقیهٔ کاربرا خطای 503 بده.
این کد تو بخش مشترک ریاکت هست، پس به یه فریمورک خاص محدود نمیشه. عملاً هر اپ Next.js 14 به بالا یا هر setup دیگهٔ React Server Components که حداقل یه server action در دسترس داشته باشه، آسیبپذیره. راهحل ریاکت این بود که یه wrapper دور دادههای فرم بذاره که جای آخرین خوندهشده رو نگه میداره و هر فیلد رو بعد از استفاده حذف میکنه. اینطوری همهٔ اشارهگرها با هم یه بار لیست رو میگردن، نه هر کدوم از اول.
نویسنده میگه مشکل رو ۲۱ آوریل به Meta گزارش داده، ۶ می پچ شده، ولی هیچ جوابی جز تأیید خودکار نگرفته و اسمش هم تو advisory نیومده. برای همین بعد از چند ماه صبر، جزئیات رو منتشر کرده.
نکات کلیدی:
- شناسهٔ آسیبپذیری CVE-2026-23870 و advisory با شناسهٔ GHSA-rv78-f8rc-xrxh هست.
- نسخههای پچشده: 19.0.6، 19.1.7 و 19.2.6؛ هر نسخهٔ پایینتر از اینا تو شاخهٔ 19.0 تا 19.2 آسیبپذیره.
- پکیجهای درگیر: react-server-dom-webpack، react-server-dom-turbopack و react-server-dom-parcel؛ react-server-dom-esm هم همین کد رو داره.
- درخواست مخرب حدود ۹۰۰ کیلوبایته و برای actionهای صفحات عمومی هیچ حسابی لازم نیست.
- هر درخواست تو محیط شبیه پروداکشن حدود ۱۰ ثانیه سرور رو قفل میکرد.




