Анализ CVE-2025-6554: движок возвращал “невидимое” значение вместо ошибки — и открыл память
NewsMakerИстория одной "дыры", ставшей эксплойтом.
В июне 2025 года в JavaScript-движке V8 была обнаружена критическая уязвимость, получившая идентификатор CVE-2025-6554 . Она связана с особенностями обработки переменных, находящихся в состоянии "временной мёртвой зоны" (TDZ), и уже активно использовалась злоумышленниками до выхода исправления от Google.
Исследователь с ником @DarkNavyOrg опубликовал пример , демонстрирующий суть проблемы. В центре уязвимости — функция, в которой переменная
В демонстрационном коде уязвимость возникает при удалении свойства с помощью конструкции
В прошлом аналогичная уязвимость уже возникала в 2023 году — тогда CVE-2023-3079 также использовала "hole" для обхода защиты и выполнения произвольного кода. В текущем случае проблема повторилась, но в другой части движка. В ходе анализа выяснилось, что проблема кроется в генерации байткода. В момент выполнения
Причина кроется в механизме управления так называемыми "bitmap'ами" проверки hole-состояний. Эти структуры фиксируют, какие переменные уже были проверены на наличие "дыры", чтобы не дублировать проверки и не снижать производительность. Однако если проверка выполняется вне нужной области видимости, она может ошибочно считаться глобальной. В результате при следующем обращении к переменной проверка пропускается, и движок возвращает значение, которое по идее не должно было попасть в руки пользователя.
Патч, выпущенный Google, корректирует этот механизм. Теперь каждый участок байткода имеет изолированную область для контроля hole-проверок, и возврат значения переменной снова сопровождается корректной валидацией. Это исключает возможность утечки "дыры" в обход стандартных защитных механизмов.
Сама уязвимость выглядит как нечто технически сложное и специфическое, но последствия её эксплуатации могут быть весьма серьёзными. Получив доступ к скрытым внутренним значениям V8, атакующий может сконструировать примитивы для чтения и записи произвольной памяти, что в итоге приводит к выполнению произвольного кода в контексте браузера. Это особенно опасно в случае атак через JavaScript в браузерах Chrome и других продуктах на базе Chromium.
Инцидент показывает, насколько важно точно и строго соблюдать логику обработки ошибок и промежуточных состояний даже на уровне генерации байткода. В данном случае одна незащищённая переменная оказалась точкой входа для полноценной уязвимости нулевого дня , уже используемой в реальных атаках.

В июне 2025 года в JavaScript-движке V8 была обнаружена критическая уязвимость, получившая идентификатор CVE-2025-6554 . Она связана с особенностями обработки переменных, находящихся в состоянии "временной мёртвой зоны" (TDZ), и уже активно использовалась злоумышленниками до выхода исправления от Google.
Исследователь с ником @DarkNavyOrg опубликовал пример , демонстрирующий суть проблемы. В центре уязвимости — функция, в которой переменная
y
используется до объявления. В JavaScript это должно приводить к ошибке ReferenceError, поскольку переменные, объявленные через let
и const
, недоступны до момента инициализации. Однако в V8 подобные случаи обрабатываются особым образом — вместо ошибки движок возвращает скрытое значение под названием "hole", которое служит маркером незаполненного места в массиве или недоступной переменной. В демонстрационном коде уязвимость возникает при удалении свойства с помощью конструкции
delete x?.[y]?.a
, где переменная y
ещё не определена. В нормальной ситуации обращение к ней должно завершиться ошибкой. Однако из-за недоработки в логике байткода, когда x
имеет значение undefined
, движок пропускает проверку y
на наличие значения hole
и просто возвращает его, позволяя использовать это значение в дальнейшем. В прошлом аналогичная уязвимость уже возникала в 2023 году — тогда CVE-2023-3079 также использовала "hole" для обхода защиты и выполнения произвольного кода. В текущем случае проблема повторилась, но в другой части движка. В ходе анализа выяснилось, что проблема кроется в генерации байткода. В момент выполнения
delete
-операции проверка на наличие "hole" происходит корректно, но затем результат сохраняется и воспринимается как проверенный, даже при последующих обращениях. Это приводит к тому, что при возврате значения y
из функции соответствующая проверка уже не выполняется, и движок возвращает необработанный "hole". Причина кроется в механизме управления так называемыми "bitmap'ами" проверки hole-состояний. Эти структуры фиксируют, какие переменные уже были проверены на наличие "дыры", чтобы не дублировать проверки и не снижать производительность. Однако если проверка выполняется вне нужной области видимости, она может ошибочно считаться глобальной. В результате при следующем обращении к переменной проверка пропускается, и движок возвращает значение, которое по идее не должно было попасть в руки пользователя.
Патч, выпущенный Google, корректирует этот механизм. Теперь каждый участок байткода имеет изолированную область для контроля hole-проверок, и возврат значения переменной снова сопровождается корректной валидацией. Это исключает возможность утечки "дыры" в обход стандартных защитных механизмов.
Сама уязвимость выглядит как нечто технически сложное и специфическое, но последствия её эксплуатации могут быть весьма серьёзными. Получив доступ к скрытым внутренним значениям V8, атакующий может сконструировать примитивы для чтения и записи произвольной памяти, что в итоге приводит к выполнению произвольного кода в контексте браузера. Это особенно опасно в случае атак через JavaScript в браузерах Chrome и других продуктах на базе Chromium.
Инцидент показывает, насколько важно точно и строго соблюдать логику обработки ошибок и промежуточных состояний даже на уровне генерации байткода. В данном случае одна незащищённая переменная оказалась точкой входа для полноценной уязвимости нулевого дня , уже используемой в реальных атаках.