JSON Toolkit

__proto__ ইনজেকশন কী

সংক্ষেপে: `JSON.parse` `__proto__`-কে সাধারণ কি ধরে; ক্ষতি হয় রিকার্সিভ মার্জে যা `Object.prototype`-এ লেখে, ফলে প্রতিটি অবজেক্ট আক্রমণকারীর প্রপার্টি উত্তরাধিকার পায়।

উন্নত~5 মিনিট পড়াপ্রকাশ 2026-10-30আপডেট 2026-10-30
প্রোটোটাইপ দূষণ কীভাবে কাজ করে ও কীভাবে আটকাবেন

মূল কথা: যেকোনো মার্জের আগে __proto__, constructor ও prototype আটকান, অবিশ্বস্ত ইনপুট Object.create(null)-এ মার্জ করুন, আর CI-তে একটি প্রোটোটাইপ দাবি যোগ করুন; কেবল লাইব্রেরি patched করাই যথেষ্ট নয়।

এক বাক্যে: __proto__ নামের অবিশ্বস্ত কি রিকার্সিভ মার্জের সঙ্গে মেলে, আর মার্জ প্রোটোটাইপে লেখে।

পুনরুৎপাদন

function merge(target, source) {
  for (const key in source) {
    if (typeof source[key] === 'object' && source[key] !== null) {
      target[key] = target[key] || {};
      merge(target[key], source[key]);
    } else {
      target[key] = source[key];
    }
  }
  return target;
}

merge({}, JSON.parse('{"__proto__": {"isAdmin": true}}'));
console.log({}.isAdmin);   // true

কোনো ব্যবসায়িক অবজেক্ট ছোঁয়া হয়নি। Object.prototype ছোঁয়া হয়েছে, আর এখন প্রতিটি অবজেক্টে isAdmin।

JSON.parse দোষী নয় কেন

const data = JSON.parse('{"__proto__": {"a": 1}}');
Object.getOwnPropertyNames(data);                  // [ '__proto__' ]
Object.getPrototypeOf(data) === Object.prototype;  // true, untouched

__proto__ সাধারণ নিজস্ব প্রপার্টি হিসেবে আসে। বিপদ পুরোটাই পরে মার্জ, deep-copy বা পাথ দিয়ে সেট করা কোডে — _.merge, কিছু Object.assign প্যাটার্ন, আর অগণিত হাতে লেখা set(obj, path, value) হেল্পার।

প্রভাব

  • অনুমোদন বাইপাস: if (user.isAdmin) অনিবার্যভাবে সত্য হয়
  • ডেটা বিকৃতি: অপ্রত্যাশিত ফিল্ড সংরক্ষিত রেকর্ডে সিরিয়ালাইজ হয়
  • ডিনায়াল অফ সার্ভিস: প্রোটোটাইপে জোড়া বড় অবজেক্ট স্থায়ীভাবে মেমরি বাড়ায়
  • উত্তরণ: টেমপ্লেট ইঞ্জিন বা কমান্ড রানারের সঙ্গে মিলে রিমোট কোড এক্সিকিউশন ঘটিয়েছে

চার প্রতিরক্ষা

কি ফিল্টার করুন।

const FORBIDDEN_KEYS = new Set(['__proto__', 'constructor', 'prototype']);

কেবল __proto__ আটকানো যথেষ্ট নয়: constructor.prototype একই জায়গায় পৌঁছায়।

নাল-প্রোটোটাইপ অবজেক্টে মার্জ করুন।

const safeTarget = Object.create(null);

প্রোটোটাইপ চেইন না থাকায় __proto__ নিছক স্ট্রিং কি।

in-এর বদলে Object.hasOwn ব্যবহার করুন। in প্রোটোটাইপ চেইন দেখে।

নির্ভরতা patched রাখুন। lodash, deepmerge ও json-patch — সবই এই শ্রেণির বাগের সমাধান প্রকাশ করেছে। npm audit দেখুন।

ঠিক থেকেছে কি না যাচাই

__proto__ ও constructor ধারণকারী পেললোড আপনার মার্জের মধ্য দিয়ে চালান, তারপর দাবি করুন:

console.log({}.polluted);                 // undefined
console.log(Object.prototype.polluted);   // undefined

CI-তে একটি দাবি, প্রায় শূন্য খরচ, পরের রিফ্যাক্টর থেকে রিগ্রেশন ধরে।

সাধারণ প্রশ্ন

মার্জে কোন কি ফিল্টার করা উচিত?

__proto__, constructor ও prototype একসঙ্গে আটকান। কেবল __proto__ ফিল্টার যথেষ্ট নয়, কারণ constructor.prototype একই প্রোটোটাইপে পৌঁছায়।

Object.create(null) লেখা আটকায় কেন?

নাল-প্রোটোটাইপ অবজেক্টে প্রোটোটাইপ চেইন নেই, তাই __proto__ সাধারণ স্ট্রিং কি থাকে। এটি ডেটা কন্টেইনার হিসেবে কাজ করে, কিন্তু কি-ফিল্টারিং বা নির্ভরতা হালনাগাদ প্রতিস্থাপন করে না।

CI-তে প্রোটোটাইপ দূষণ কীভাবে পরীক্ষা করব?

__proto__ ও constructor ধারণকারী পেললোড মার্জের মধ্য দিয়ে পাঠিয়ে দাবি করুন {}.polluted ও Object.prototype.polluted — দুটোই undefined। একটি দাবি প্রায় কিছুই খরচ করে না আর পরের রিফ্যাক্টর থেকে রিগ্রেশন ধরে।

আরও পড়ুন