flawopen.com/Teardowns/cve-2024-27980-nodejs-windows-batch-injection
CVE-2024-27980: Node.js в Windows
В Windows функции spawn() и spawnSync() могли допустить внедрение команд при запуске batch-файлов даже без параметра shell.
Представьте: программа передаёт аргументы batch-файлу, но Windows запускает его через командный интерпретатор. Интерпретатор может трактовать аргументы как синтаксис команды. Node.js устранил проблему, запретив прямой запуск batch-файлов, а не пытаясь угадать безопасное экранирование каждого аргумента.
Ключевые понятия и термины
child_process.spawn()- Асинхронный API Node.js для запуска процесса с исполняемым файлом и списком аргументов.
Batch-файл- Файл .bat или .cmd, который интерпретирует оболочка Windows; это не обычный исполняемый файл с единым разбором argv.
Метасимвол оболочки- Символ, смысл которого задаётся командным интерпретатором и может менять структуру команды.
EINVAL- Код ошибки, которым Node.js отклоняет небезопасный прямой запуск batch-файла.
Связи со стандартами
- Ссылка CWE для слабого места, описанного в этом руководстве: CWE-77
Анализ первопричины
В Windows файлы .bat и .cmd обрабатываются командной оболочкой; их аргументы не всегда можно однозначно экранировать. Согласно уведомлению Node.js, вредоносный аргумент мог внедрить команду через child_process.spawn() и spawnSync() даже без включённого shell. Upstream-патч распознаёт имена с окончанием .bat или .cmd без учёта регистра и возвращает EINVAL до вызова uv_spawn(). Исправление не реализует sanitizeBatchArg() и не доказывает безопасность shell: true. Позднее обнаружили неполноту исправления для других расширений batch-файлов (CVE-2024-36138); установите версию с обоими исправлениями.
Пошаговый сценарий атаки
Приложение вызывает API процессов
В Windows приложение запускает через child_process.spawn() или spawnSync() файл .bat либо .cmd с аргументами, которые могут зависеть от внешних данных.
Цель — batch-файл
Для batch-файлов действуют правила командной оболочки; список аргументов сам по себе не исключает интерпретацию метасимволов.
Windows интерпретирует аргументы
Уязвимое поведение позволяло интерпретировать аргумент как синтаксис команды даже при shell: false.
Node.js блокирует прямой запуск
Патч возвращает EINVAL при прямом запуске .bat/.cmd. CVE-2024-36138 выявила остаточную проблему с другими расширениями; нужны версии с обоими исправлениями.
Исходный код: Уязвимый vs Защищённый вариант
// Фрагмент src/process_wrap.cc до исправления безопасности
node::Utf8Value file(env->isolate(), file_v);
options.file = *file;
// Имя файла передавалось в uv_spawn() без отклонения пакетных файлов.
// Фрагмент исправления CVE-2024-27980 в upstream
node::Utf8Value file(env->isolate(), file_v);
options.file = *file;
// Аргументы пакетных файлов не всегда можно однозначно экранировать.
if (IsWindowsBatchFile(options.file))
err = UV_EINVAL;
if (err == 0) {
err = uv_spawn(env->event_loop(), &wrap->process_, &options);
wrap->MarkAsInitialized();
}
Чек-лист по защите системы для инженеров
- ✓Обновитесь до поддерживаемой версии Node.js с исправлениями
CVE-2024-27980иCVE-2024-36138. - ✓Не запускайте batch-скрипты с внешними данными; по возможности используйте исполняемый файл напрямую с проверенными аргументами.
- ✓Если shell необходим, считайте shell: true запуском команд и применяйте строгую проверку и авторизацию.
- ✓Добавьте тесты Windows для
spawn()иspawnSync()с batch-расширениями и проверяйте безопасный отказ EINVAL.