πŸ”΄ HardFix the CodeπŸ› Debug Challenge

Prototype pollution vulnerability

Buggy Code β€” Can you spot the issue?

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

// Attack:
merge({}, JSON.parse('{"__proto__": {"isAdmin": true}}'));
console.log({}.isAdmin); // true β€” every object is now an admin!

Fixed Code

function merge(target, source) {
  for (const key of Object.keys(source)) { // own keys only
    // Block dangerous keys
    if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
      continue;
    }
    if (typeof source[key] === 'object' && source[key] !== null) {
      target[key] = merge(target[key] || {}, source[key]);
    } else {
      target[key] = source[key];
    }
  }
  return target;
}

// Or use structuredClone + Object.assign for safe merging

Bug Explained

Bug: __proto__ is a special property. Setting target["__proto__"] doesn't create an own property β€” it modifies Object.prototype, polluting all objects.

Explanation: Block __proto__, constructor, and prototype keys explicitly. Use Object.keys() instead of for...in to iterate own properties only.

Key Insight: Prototype pollution: __proto__ assignment modifies Object.prototype. Always sanitize keys when merging user-controlled objects.

More Fix the Code Debug Challenges

🟒 EasyDeep clone breaks with JSON.stringifyβ†’πŸŸ‘ Mediumthis lost in event listenerβ†’πŸŸ‘ MediumObject mutation in array mapβ†’πŸŸ‘ MediumProxy trap modifies original object directlyβ†’

Practice spotting bugs live β†’

38 debug challenges with AI hints

πŸ› Try Debug Lab