Вы доверяете structuredClone защиту от прототип-поллюшена? Зря. В Edge Runtime старых версий (V8) баг позволяет Symbol-ключам с именем
__proto__ при клонировании записаться как строковые ключи, обходя стандартные проверки. Это особенно опасно в API-серверах на Node.js и edge-функциях, где входящие данные не проходят валидацию.Как это работает
Обычная защита от prototype pollution строится на проверке ключей через
Object.keys() или for...in. Но эти методы игнорируют Symbol-ключи. Злоумышленник вставляет символ с именем __proto__:const payload = {
[Symbol('__proto__')]: { polluted: true }
};
const clean = structuredClone(payload);В уязвимых версиях Edge Runtime этот символ неправильно обрабатывается как строковой ключ, и объект
clean получает прототип-загрязнение.Почему это изящно
-
Object.keys() и for...in не видят Symbol-ключи — стандартная проверка их пропускает.-
JSON.parse(JSON.stringify()) теряет Symbol — многие разработчики перешли на structuredClone, считая его безопаснее.- Но structuredClone обрабатывает Symbol-ключи (кроме well-known). Механизм безопасного клонирования становится вектором атаки через незаметные Symbol.
Типичная ошибка
Думать, что structuredClone изолирует от prototype pollution, если вы проверяете только строковые ключи. В code review я встречал код, где после глубокого клонирования входных данных объект проверялся
Object.keys() — Symbol остались незамеченными.Production-совет
Для временных данных из ненадёжных источников используйте
Object.create(null) — он блокирует прототипную цепочку. Дополнительно, проверяйте Symbol-ключи вручную: Object.getOwnPropertySymbols(obj). Если вы используете edge runtime — обновляйте его до актуальной версии, где этот баг исправлен.Вывод: structuredClone не является панацеей от prototype pollution — Symbol-ключи с именами
__proto__ могут обходить защиту, если вы не обрабатываете их явно.