Перейти к содержимому
← Каталог nodejs Prototype Pollution

Prototype Pollution → RCE через гаджет в EJS

Админ-панель SecureShop рекурсивно сливает JSON-патч предпочтений с in-memory объектом, что позволяет загрязнить Object.prototype. Превью дашборда через EJS читает опции компиляции через цепочку прототипов — это превращает prototype pollution в RCE-гаджет и даёт чтение LAB_FLAG.

hardnodejsPro
Задача
# Prototype Pollution → RCE через gadget в шаблонизаторе ## Контекст SecureShop — интернет-магазин с админ-панелью. Помимо управления каталогом и пользователями, админам доступна тонкая настройка собственного дашборда: заголовок страницы, текст футера, имя пользователя в приветствии. Бэкенд получает JSON-патч и рекурсивно сливает его с in-memory объектом предпочтений, чтобы клиент мог менять только нужные поля, не перезаписывая остальные. Когда админ открывает превью дашборда, сервер берёт текущие предпочтения и рендерит фрагмент HTML через шаблонизатор. Текст шаблона зашит в коде — пользователь не контролирует его напрямую. На первый взгляд поверхность атаки минимальна: значения внутри шаблона корректно экранируются, а тело шаблона недоступно извне. ## Уязвимость В приложении две независимые проблемы складываются в одну цепочку. 1. **Рекурсивный merge без фильтра ключей.** Функция, объединяющая JSON-патч с предпочтениями, перебирает все ключи входного объекта и пишет их в целевой объект. Если в JSON встречается ключ `__proto__`, JSON-парсер сохраняет его как обычное собственное свойство, а merge на следующей итерации заходит «внутрь» этого ключа — то есть начинает писать прямо в `Object.prototype`. Это классический prototype pollution: любой обычный объект в процессе теперь наследует загрязнённые свойства. 2. **Шаблонизатор читает опции компиляции через прототип.** При вызове рендера с двумя аргументами шаблонизатор внутри обращается к объекту опций и читает из него имя выходной переменной, имя локалов, функцию экранирования и т.п. — обычным доступом по точке. Если объект опций пуст, эти обращения «проваливаются» в `Object.prototype` и возвращают то, что туда положил атакующий. Прочитанные значения шаблонизатор подставляет **дословно** в тело генерируемой JavaScript-функции — то есть атакующий инжектит произвольный JS-код в скомпилированный шаблон. Каждая из проблем по отдельности кажется безобидной: «слить ключи» и «прочитать опцию по умолчанию» — рутинные операции. Вместе они превращают POST-эндпоинт настроек админа в RCE-примитив: загрязнённый прототип становится **гаджетом**, который шаблонизатор вшивает в свой compiled output. ## Точки входа - Форма входа `/login` — стандартная авторизация SecureShop. Чтобы достичь админских эндпоинтов, нужен аккаунт с ролью `admin`. - Эндпоинт `POST /admin/preferences` — принимает JSON-патч предпочтений админа и рекурсивно сливает его с in-memory объектом. Требует роль admin. - Эндпоинт `GET /admin/dashboard-preview` — рендерит фрагмент дашборда через шаблонизатор, читая текущие предпочтения. Тот же admin guard. ## Цель Прочитать значение переменной окружения `LAB_FLAG` процесса сервера и получить его в теле HTTP-ответа. ## Что вы научитесь делать - Распознавать prototype pollution как класс уязвимости и понимать, чем он опаснее обычного «лишнего ключа в объекте». - Строить gadget chain: pollution → читающая прототип библиотека → RCE-сток. - Понимать, почему изолированные проверки безопасности (escape пользовательских данных, фиксированный шаблон, проверка ролей) не помогают, если архитектура содержит непротестированный путь от ввода до прототипа.

Похожие лабораторные

Ещё лабораторные по этому типу уязвимости

prototype-pollution

Prototype Pollution: загрязнение Object.prototype через recursive merge

Эндпоинт обновления пользовательских настроек в Express делает recursive merge тела запроса без фильтрации ключа __proto__. Загрязни Object.prototype.isAdmin и получи доступ к /admin/flag.

+60 XP ~40 минут
nodejsmediumPro
Exploit Fix
prototype-pollution

Prototype Pollution: загрязнение Object.prototype приводит к DoS публичных эндпоинтов

Express-эндпоинт POST /profile/settings делает рекурсивный merge JSON-объекта в per-user настройки без фильтрации __proto__. Атакующий загрязняет Object.prototype, после чего hot-path обработчик /catalog падает с 500 на каждом запросе — Denial of Service. Endpoint /api/incident-response регистрирует инцидент и выдаёт флаг.

+90 XP ~75 минут
nodejshardPro
Exploit Fix
🚧 Сайт в разработке. Полный функционал пока недоступен. Все вопросы — support@hackandfix.ru