Путаница типов в ExternalCopy из isolated-vm позволяет перехватить управление хост-процессом

vulnerability

В библиотеке isolated-vm, предназначенной для выполнения недоверенного JavaScript в изолированной среде, нашли уязвимость, которая позволяет коду внутри песочницы атаковать хост-процесс. Проблема затрагивает механизм ExternalCopy, используемый для передачи данных между изолятами V8 (JavaScript-движка, применяемого в Chrome и Node.js). Злоумышленник может вызвать повреждение памяти хост-процесса, перехватить поток управления и выполнить произвольный код. Уязвимость получила идентификатор GHSA-864f-rcv7-6rh4, CVE пока не присвоили. Она присутствует во всех версиях isolated-vm до 7.0.1 и 6.2.0.

Детали уязвимости

Механизм ExternalCopy обеспечивает обмен значениями между изолятами V8. Изоляты представляют собой независимые экземпляры движка JavaScript со своими кучами и встроенными объектами. Они не разделяют объектный граф, поэтому при передаче библиотека сериализует значения. Для оптимизации ExternalCopy поддерживает опцию transferList, которая позволяет передавать объекты ArrayBuffer без копирования памяти. Вместо этого библиотека отсоединяет буфер от источника и передаёт его целиком. Проблема кроется в обработке transferList.

Уязвимость относится к типу путаницы типов. При создании ExternalCopy библиотека дважды обходит переданный список transferList. На первом проходе она проверяет каждый элемент на принадлежность к ArrayBuffer. На втором проходе код не выполняет проверку, а напрямую приводит элемент к типу ArrayBuffer через непроверяемое преобразование. Такая логика корректна только в том случае, если оба прохода видят одинаковые значения. Однако transferList является обычным JavaScript-массивом, и чтение его элементов может запускать пользовательские геттеры. Атакующий может определить геттер, который при первом обращении вернёт настоящий ArrayBuffer, а при втором - произвольное значение. В результате на втором проходе код получает не тот объект, что прошёл проверку. Это классическая ошибка вида "проверка-использование", когда состояние меняется между проверкой и использованием.

Дальнейшая обработка приводит к разыменованию указателя, управляемого атакующим. Исследователи продемонстрировали, что с помощью такого подхода можно вызвать надёжный отказ в обслуживании, приведя хост-процесс к падению с ошибкой сегментации. Более того, используя в качестве подменённого объекта JavaScript-строку, удалось подменить байты, интерпретируемые как поля нативного объекта. В итоге код вышел на непрямой вызов через указатель на таблицу виртуальных методов, что превращает уязвимость в примитив для перехвата управления. Исследователи из EndorLabs сообщили о демонстрации перенаправления выполнения в хост-процессе на выбранную функцию из стандартной библиотеки, но полные детали эксплойта они не раскрывают.

Особенность этой уязвимости в том, что она достижима изнутри песочницы при наличии всего одного объекта ivm.Reference. Такой объект является стандартным способом предоставить изолированному коду доступ к каким-либо возможностям хост-процесса. Используя его, недоверенный код получает конструктор ExternalCopy и может собрать вредоносный transferList. Из-за этого любое приложение, которое запускает пользовательские или модельные сценарии и делится хотя бы одной ссылкой с песочницей, оказывается под угрозой.

isolated-vm широко используют в проектах, связанных с автоматизацией, искусственным интеллектом и разработкой без написания кода. Среди них n8n, Activepieces, Mastra AI, Budibase, Sim.ai, Directus и Rocket.Chat. Во многих из этих систем библиотека выступает ключевым элементом безопасности, отделяющим выполняемый код от основной инфраструктуры. Поэтому побег из песочницы представляет собой наихудший сценарий для таких платформ.

Важно подчеркнуть, что атака не нарушает модель изоляции V8. Изоляты продолжают корректно разделять память, и сама безопасность движка не затрагивается. Проблема заключается в нативном слое C++, который выполняет сериализацию значений при пересечении границы изолята. Именно этот связующий код оказался уязвимым. Ошибка возникла из-за повторного чтения управляемого атакующим объекта в середине чувствительной операции и непроверяемого приведения типа. Это показывает, что ошибками в нативной прослойке можно скомпрометировать даже надёжную изоляцию.

Разработчик isolated-vm выпустил исправления в версиях 7.0.1 и 6.2.0. Патч включает запрет на выполнение JavaScript во время операции копирования при помощи специального механизма движка V8. Это исключает возможность вызова геттеров, прокси и других пользовательских функций в процессе обработки transferList. Организациям, использующим isolated-vm, следует немедленно обновиться до указанных версий. Кроме того, разработчикам следует минимизировать количество объектов Reference, передаваемых недоверенному коду, и проверить, не может ли злоумышленник влиять на данные, которые попадают в ExternalCopy или transferList.

Эта уязвимость продолжает серию исследований, показывающих, что границы безопасности в песочницах чаще всего ломаются не в изолирующем примитиве, а в коде, который связывает его с внешним миром. Написанный на C++ связующий слой обрабатывает сырые указатели и перечитывает атакующие объекты, поэтому требует такого же внимания, как и сама изоляция. По мере роста числа платформ, выполняющих код, сгенерированный искусственным интеллектом, подобные ошибки могут становиться всё более значимыми.

Ссылки

Комментарии: 0