Выбор ответа Senior Безопасность бэкенда обновлено

Prototype pollution через merge

Вопрос

Что выведет код?

function merge(target, src) {
  for (const k in src) {
    if (typeof src[k] === 'object') {
      target[k] = target[k] || {};
      merge(target[k], src[k]);
    } else target[k] = src[k];
  }
  return target;
}
merge({}, JSON.parse('{"__proto__": {"isAdmin": true}}'));
console.log({}.isAdmin);

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: true. JSON.parse создаёт обычное собственное свойство с именем proto.

Варианты ответа

  1. trueправильный ответ
  2. undefined
  3. TypeError
  4. false

Разбор

JSON.parse создаёт обычное собственное свойство с именем __proto__. Но в merge выражение target["__proto__"] возвращает Object.prototype, и рекурсия записывает isAdmin прямо в него. Теперь у любого объекта есть isAdmin: true. Это prototype pollution.

  • undefined было бы при безопасном слиянии.
  • Ошибки не возникает, запись в прототип разрешена.
  • false негде взять, записано true.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме