چرا نود نمیتونه جلوی Prototype Pollution رو بگیره
خلاصهٔ کاملتر
نویسندهی این پست که سالهاست روی نود کار میکنه، میگه هر چند هفته یه گزارش امنیتی با یه الگوی تکراری میرسه: یکی یه «گَجت» پیدا کرده؛ جایی که کد یه پراپرتی رو میخونه که انتظار نداشته اصلاً وجود داشته باشه و بعد باهاش یه کار خطرناک میکنه. مثلاً child_process یه shell رو تحویل میگیره که هیچوقت بهش پاس داده نشده. گاهی این گَجت تو هستهی نودـه و بیشتر وقتها تو کتابخونهای سه لایه پایینتر تو درخت وابستگیها.
به گفتهی نویسنده جواب همیشه منفیه و دلیلش هم تنبلی نگهدارنده نیست. همهی این گزارشها یه پیششرط تو قدم صفر دارن: اپلیکیشن از قبل prototype pollution داره، یعنی مهاجم تونسته روی Object.prototype بنویسه. وقتی این اتفاق افتاده، گَجتی که پیدا شده دیگه خودِ آسیبپذیری نیست، فقط نشونهشه؛ پشتش بیشمار راه خروج دیگه هست. مقالهی Silent Spring بهتنهایی یازده گَجت عمومی رو فقط تو هسته فهرست کرده، اون هم سقف ماجرا نبوده.
چیزی که ماجرا رو ساختاری میکنه اینه که جاوااسکریپت همهجا زنجیرهی prototype رو میخونه، اون هم نه فقط موقع صدا زدن متد؛ خودِ سینتکس هم این کارو میکنه: destructuring، spread، for...of، خوندن .then موقع await، تمپلیت لیترال و رگولار اکسپرشن. هر آبجکت {} که هسته میسازه هم باز از Object.prototype ارث میبره، پس یه شرط ساده روی یه آپشن مستقیم میره سراغ همون چیزی که مهاجم کاشته.
سراغ primordials هم که بری — ارجاعهایی به بیلتاینهای اصلی که موقع بالا اومدن نود گرفته میشن تا هسته با monkey-patch شدن گلوبالها نشکنه — نویسنده میگه اونها بحث یکپارچگیان، نه امنیت. تو ترد TSC هم Joyee Cheung گفته حتی پوشش صددرصدی primordials همهی حفرهها رو نمیبنده، چون ریشهی ماجرا به خودِ اسپک ECMAScript برمیگرده. Benjamin Gruenbaum هم صریح گفته prototype pollution تو هستهی نود تو برنامهی باگبانتی آسیبپذیری پذیرفته نمیشه.
جای درست دفاع، به گفتهی نویسنده، همونجاییه که بایتهای نامطمئن تبدیل به آبجکت میشن. خودِ JSON.parse چیزی رو آلوده نمیکنه و فقط یه پراپرتی معمولی به اسم proto میسازه؛ خرابی وقتی شروع میشه که یه merge بازگشتی یا Object.assign اون کلید رو به زنجیرهی واقعی prototype منتقل کنه. برای همین Fastify بادی هر ریکوئست رو بهصورت پیشفرض با secure-json-parse میخونه:
const parse = require('secure-json-parse')
parse(body, { protoAction: 'error', constructorAction: 'error' })نکات کلیدی:
- گزارشهای گَجت prototype pollution همیشه فرض میکنن اپلیکیشن از قبل آلوده شده؛ خودِ اون فرض باگ اصلیه.
- سفتکردن یه تابع خاص تو هسته چیزی رو نمیبنده، چون گَجت بعدی تو fetch، vm یا merge کانفیگ فریمورک بعدیه.
- primordials جلوی شکستن نود موقع monkey-patch رو میگیره، ولی امنیت اپلیکیشن رو تضمین نمیکنه.
- تیم نود prototype pollution هسته رو تو برنامهی باگبانتی بهعنوان آسیبپذیری قبول نمیکنه.
- دفاع واقعی سر مرزه: پارس امن بادی ریکوئست، Map برای کلیدهای نامطمئن و آبجکتهای null-prototype برای دادهی مهاجم.




