Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке забруднення прототипу (prototype pollution) у JavaScript?

У JavaScript об'єкти успадковують властивості від прототипу, і всі звичайні об'єкти мають спільний Object.prototype. Забруднення прототипу - зловмисник через дані змушує код записати властивість у сам прототип, і вона з'являється в усіх об'єктах застосунку.

Як це трапляється - рекурсивне злиття чи встановлення властивості за шляхом з даних користувача:

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];
    }
  }
}

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

({}).isAdmin;   // true - у кожного об'єкта

Ключ __proto__ вказує на прототип, тож запис іде в Object.prototype. Так само через constructor.prototype.

Наслідки:

  • обхід перевірок: if (user.isAdmin) для об'єкта, в якому поля немає, раптом дає true;
  • XSS у браузері: бібліотека читає налаштування з об'єкта опцій (options.innerHTML, options.src), а «забруднене» значення підставляється в DOM. Так атакують через параметри URL (?__proto__[x]=...) з бібліотеками, що розбирають рядок запиту у вкладені об'єкти;
  • виконання коду на сервері (Node.js): забруднені опції child_process, рушіїв шаблонів;
  • DoS - зламана логіка всього застосунку.

Захист:

  • блокувати небезпечні ключі при злитті й записі за шляхом: __proto__, constructor, prototype;
  • об'єкти без прототипу для словників з даних: Object.create(null);
  • Map замість звичайного об'єкта для довільних ключів;
  • валідація схемою (Zod) з «суворими» об'єктами - невідомі ключі відкидаються;
  • оновлювати бібліотеки злиття, розбору рядка запиту, глибокого копіювання - багато відомих CVE саме тут (lodash merge, qs, jQuery extend);
  • Object.freeze(Object.prototype) - радикальний захист, але може зламати сторонні бібліотеки.

Чим це стосується PHP-розробника: фронтенд Laravel-застосунку (Vue, React, Alpine) і Node-скрипти збирання/SSR - теж частина поверхні атаки; оновлення npm-залежностей важливе так само, як composer.

Докладніше в документації: PortSwigger: Prototype pollution

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання