Реестр расширений Open VSX, которым пользуются миллионы разработчиков через VS Code, Cursor и Windsurf, содержал критическую уязвимость. Любой злоумышленник с бесплатным аккаунтом издателя мог обойти все предпубликационные проверки безопасности и залить в маркетплейс вредоносное расширение. Причём для этого не требовалось никаких специальных привилегий и практически никаких технических навыков.

Уязвимость обнаружил исследователь компании Koi Security Оран Симхони. Он присвоил ей кодовое имя Open Sesame и поделился подробностями с изданием The Hacker News. Баг уже исправлен в версии Open VSX 0.32, которую поддерживает Eclipse Foundation.
Контекст проблемы такой: буквально в начале прошлого месяца Eclipse Foundation объявила о внедрении обязательных предпубликационных сканеров безопасности. Расширения в формате.VSIX перед публикацией должны были проходить автоматическую проверку, и те, что не проходили её, попадали на карантин для ручного ревью администраторами. Логичная мера на фоне участившихся атак через вредоносные расширения для редакторов кода.
Проблема сидела глубоко в архитектуре конвейера проверки. Java-сервис Open VSX использовал единственное булево значение для возврата результата работы сканеров. И вот в чём была катастрофа: это значение означало одновременно две совершенно разные вещи. «Сканеры не настроены» и «все сканеры упали» выдавали один и тот же результат. Вызывающий код не мог отличить штатную ситуацию от аварийной.
Эксплуатация строилась на перегрузке. Атакующий заливал в эндпоинт публикации множество вредоносных.VSIX-файлов одновременно. Конкурентная нагрузка истощала пул соединений с базой данных. Задания на сканирование безопасности не могли встать в очередь, потому что база захлёбывалась. Система фиксировала сбой, но возвращала тот самый булев — и интерпретировала его как «сканеры не настроены, проверять нечего». Вредоносное расширение автоматически получало статус «прошло проверку», активировалось и становилось доступным для скачивания.
Хуже того, встроенный механизм восстановления, который должен был повторно запускать проваленные проверки, содержал ровно тот же логический баг. То есть даже «страховочная сеть» пропускала вредоносные расширения при нагрузке на систему.
«Конвейер использовал единственное булево возвращаемое значение, которое означало и «сканеры не настроены», и «все сканеры не смогли запуститься». Вызывающая сторона не могла отличить одно от другого. Так что когда сканеры падали под нагрузкой, Open VSX трактовал это как «нечего проверять» и пропускал расширение насквозь», — объяснил Оран Симхони.
Koi Security в своём отчёте сформулировала проблему шире: «Архитектура конвейера сама по себе разумна, но единственный булев, неспособный различить «нет работы» и «что-то пошло не так», превратил всю инфраструктуру в ворота, которые открываются под давлением».
С точки зрения классификации это хрестоматийный пример «fail-open error handling» — антипаттерна, при котором система в момент сбоя не блокирует доступ, а наоборот, снимает все ограничения. Проблема встречается повсеместно, от веб-приложений до физических систем контроля доступа, и каждый раз по одной причине: разработчики объединяют разные состояния ошибки в один код возврата.
Практический урок из этой истории звучит просто: состояния отказа должны быть явными. Нельзя допускать, чтобы «работа не требуется» и «работа провалилась» возвращали одинаковое значение. Для Open VSX, Cursor и Windsurf история закончилась патчем. Но сколько подобных булевых мин тикает в других конвейерах — вопрос открытый.

Изображение носит иллюстративный характер
Уязвимость обнаружил исследователь компании Koi Security Оран Симхони. Он присвоил ей кодовое имя Open Sesame и поделился подробностями с изданием The Hacker News. Баг уже исправлен в версии Open VSX 0.32, которую поддерживает Eclipse Foundation.
Контекст проблемы такой: буквально в начале прошлого месяца Eclipse Foundation объявила о внедрении обязательных предпубликационных сканеров безопасности. Расширения в формате.VSIX перед публикацией должны были проходить автоматическую проверку, и те, что не проходили её, попадали на карантин для ручного ревью администраторами. Логичная мера на фоне участившихся атак через вредоносные расширения для редакторов кода.
Проблема сидела глубоко в архитектуре конвейера проверки. Java-сервис Open VSX использовал единственное булево значение для возврата результата работы сканеров. И вот в чём была катастрофа: это значение означало одновременно две совершенно разные вещи. «Сканеры не настроены» и «все сканеры упали» выдавали один и тот же результат. Вызывающий код не мог отличить штатную ситуацию от аварийной.
Эксплуатация строилась на перегрузке. Атакующий заливал в эндпоинт публикации множество вредоносных.VSIX-файлов одновременно. Конкурентная нагрузка истощала пул соединений с базой данных. Задания на сканирование безопасности не могли встать в очередь, потому что база захлёбывалась. Система фиксировала сбой, но возвращала тот самый булев — и интерпретировала его как «сканеры не настроены, проверять нечего». Вредоносное расширение автоматически получало статус «прошло проверку», активировалось и становилось доступным для скачивания.
Хуже того, встроенный механизм восстановления, который должен был повторно запускать проваленные проверки, содержал ровно тот же логический баг. То есть даже «страховочная сеть» пропускала вредоносные расширения при нагрузке на систему.
«Конвейер использовал единственное булево возвращаемое значение, которое означало и «сканеры не настроены», и «все сканеры не смогли запуститься». Вызывающая сторона не могла отличить одно от другого. Так что когда сканеры падали под нагрузкой, Open VSX трактовал это как «нечего проверять» и пропускал расширение насквозь», — объяснил Оран Симхони.
Koi Security в своём отчёте сформулировала проблему шире: «Архитектура конвейера сама по себе разумна, но единственный булев, неспособный различить «нет работы» и «что-то пошло не так», превратил всю инфраструктуру в ворота, которые открываются под давлением».
С точки зрения классификации это хрестоматийный пример «fail-open error handling» — антипаттерна, при котором система в момент сбоя не блокирует доступ, а наоборот, снимает все ограничения. Проблема встречается повсеместно, от веб-приложений до физических систем контроля доступа, и каждый раз по одной причине: разработчики объединяют разные состояния ошибки в один код возврата.
Практический урок из этой истории звучит просто: состояния отказа должны быть явными. Нельзя допускать, чтобы «работа не требуется» и «работа провалилась» возвращали одинаковое значение. Для Open VSX, Cursor и Windsurf история закончилась патчем. Но сколько подобных булевых мин тикает в других конвейерах — вопрос открытый.