Prototype Pollution

Я разбираю реальные веб‑уязвимости и показываю, как их искать, эксплуатировать в безопасной среде и закрывать в проде. Без воды: чек‑листы атак, редкие кейсы, ошибки разработчиков и практики защиты от CSRF, XXE, Prototype Pollution, десериализации, race conditions, XSS и не только. Если вы пишете веб или проверяете его на прочность — вам сюда.

prototype pollutionjavascriptweb security

💠 Предисловие

В JavaScript почти все объекты наследуют свойства и методы через prototype chain — цепочку прототипов. Если у объекта нет собственного свойства, движок идет выше по цепочке и ищет его в прототипе. Именно поэтому объект может "уметь" что-то, даже если это явно в нем не записано.

Prototype Pollution — это уязвимость, при которой атакующий может изменить прототип объектов приложения и тем самым незаметно "подмешать" свойства или значения в другие объекты, которые с ним напрямую вообще не связаны.

🟡Тип: Web, Client-Side / Server-Side

🟡Как это работает в общих чертах:

  1. Приложение принимает объект из недоверенного источника
  2. Объединяет его с другим объектом, копирует поля, парсит query/body/json без жесткой фильтрации
  3. Специальные ключи, например __proto__, constructor.prototype, prototype попадают в процесс merge / assignment
  4. В результате меняется не один конкретный объект, а поведение множества объектов в приложении через цепочку прототипов

Главная опасность в том, что само "загрязнение" часто выглядит безобидно и даже не ломает приложение сразу. Но после этого любой участок кода, который опирается на свойства объекта, может начать работать по-другому.

🟡Пример уязвимого кода

deepMerge(defaultConfig, JSON.parse(req.body))

🟥Если deepMerge не фильтрует опасные ключи, то пользовательские данные могут изменить прототип вместо обычной вложенной структуры.

🟡Разновидности:

  • Client-Side - эксплуатация загрязняет протитипы в DOM и остается в браузере пользователя
  • Server-Side - реализуется если бекенд приложения написан на Javascript-подобном языке (Node.js, TypeScript и пр.)

🟡Влияние:

  • Обход авторизации и эскалация привилегий, например если код доверяет полям вроде isAdmin, role, authenticated и они явно не определяются при создании объекта
  • Подмена настроек безопасности или логики приложения
  • XSS на клиенте, если polluted-свойства доходят до DOM-логики или шаблонов
  • Отказ в обслуживании, если поломать ожидаемую структуру объектов
  • В отдельных случаях — SSRF, RCE или иные критичные эффекты, если загразнение доходит до опасных участков кода и нужных gadget chain

😎 Как защититься?

  • Не смешивать недоверенные объекты с внутренними структурами "как есть"
  • Фильтровать и явно запрещать опасные ключи (__proto__, prototype, constructor)
  • Использовать безопасные структуры данных там, где это уместно, например Map или объекты через Object.create(null)
  • Использовать schema validation и allowlist полей вместо парадигмы "принимаем любой JSON"
  • Обновлять библиотеки для merge / parsing / cloning, т.к. prototype pollution очень часто живет именно в зависимостях
  • Проверять только собственные свойства объекта через Object.hasOwn() / hasOwnProperty, а не доверять значениям из prototype chain
  • Не строить критичную логику на "если поле не задано, значит false" без явной инициализации

Стоит отдельно сказать, что просто почистить пару известных гаджетов — обычно слабая защита. Проблема не только в конкретном sink'е, а в самом факте неконтролируемого изменения прототипа. Пока сохраняется возможность загрязнять объекты, новые способы применения почти всегда найдутся.

📖 Имхо-зона

Еще одна интересная уязвимость, для качественной эксплуатации которой нужно читать много кода (JS-кода, что большинство избегает). Самое интересное при ее изучении - смотреть на борьбу защитных механизмов, созданных для противодействия ей, и того, как их обходят с помощью той же самой уязвимости. Вообще, осознание этой баги скорее всего откроет вам понимание того, как в принципе работает JavaScript (я так свое время переоткрыл для себя fetch-конструкции), так что если хотите стать крутым вебером, то рано или поздно вам нужно будет пройти через эту уязвимость. Из ресурсов, которые существуют, лучше всего это объяснено в Portswigger Web Security Academy - объяснение там мне понравилось даже больше, чем в OSWE (в защиту OSWE скажу, что там вы глубже поймете теорию этой баги).

#edu #vuln #web #prototype_pollution

☠️ Hunt Or Be Hunted

Инфографика: блок‑схема и диаграмма Prototype Pollution в JavaScript — потоки данных, уязвимые merge‑операции и последствия для объектов.
Схема, показывающая, как загрязнение прототипа влияет на объекты и потоки данных.

Дискуссия

Daniil Filippov
Леша в свою очередь наследовал ловкость самурая и хитрость мудреца в борьбе с малварью 😎 Воин света 🙏
Присоединиться к обсуждению →

Читайте так же