flawopen.com/Teardowns/cve-2024-27980-nodejs-windows-batch-injection
CVE-2024-27980: Windows용 Node.js
Windows에서 shell 옵션 없이 batch 파일을 실행할 때 spawn()과 spawnSync()로 명령 삽입이 가능했습니다.
프로그램이 batch 파일에 인수를 전달해도 Windows는 명령 인터프리터를 통해 파일을 실행합니다. 인터프리터는 인수를 명령 구문으로 해석할 수 있습니다. Node.js는 인수를 안전하게 이스케이프하는 방법을 추측하지 않고 batch 파일의 직접 실행을 거부하도록 수정했습니다.
핵심 개념 및 용어
child_process.spawn()- 실행 파일과 인수 목록으로 프로세스를 시작하는 Node.js 비동기 API입니다.
Batch 파일- Windows 셸이 해석하는 .bat/.cmd 파일로, 일반 실행 파일의 보편적인 argv 파싱과 다릅니다.
셸 메타문자- 명령 인터프리터에 따라 의미가 달라지고 명령 구조를 바꿀 수 있는 문자입니다.
EINVAL- Node.js가 안전하지 않은 batch 파일 직접 실행을 거부할 때 반환하는 오류 코드입니다.
프레임워크 매핑
- 이 가이드에서 설명하는 약점의 CWE 참조: CWE-77
근본 원인 분석 (Root Cause)
Windows에서 .bat와 .cmd 파일은 셸이 해석하며 인수를 항상 모호함 없이 이스케이프할 수 있는 것은 아닙니다. Node.js 보안 공지에 따르면 shell을 켜지 않아도 child_process.spawn() 및 spawnSync()에 전달된 악의적 인수로 명령을 삽입할 수 있었습니다. upstream 패치는 대소문자를 구분하지 않고 .bat/.cmd 확장자를 감지한 뒤 uv_spawn() 전에 EINVAL을 반환합니다. 이 수정은 sanitizeBatchArg()를 구현한 것이 아니며 shell: true가 안전하다는 뜻도 아닙니다. 후속 공지에서는 다른 batch 확장자에 대한 수정 누락이 보고됐습니다(CVE-2024-36138). 두 수정이 모두 포함된 버전을 사용하세요.
단계별 공격 실행 흐름
앱이 프로세스 API 호출
Windows에서 앱은 외부 입력의 영향을 받을 수 있는 인수와 함께 child_process.spawn() 또는 spawnSync()로 .bat/.cmd를 실행합니다.
대상은 batch 파일
batch 파일에는 셸 규칙이 적용됩니다. 인수 배열만으로 메타문자 해석을 막을 수 없습니다.
Windows가 인수 해석
취약한 동작은 shell: false여도 인수를 명령 구문으로 해석할 수 있었습니다.
Node.js가 직접 실행 차단
패치는 .bat/.cmd 직접 실행에 EINVAL을 반환합니다. CVE-2024-36138은 다른 확장자에 남은 결함을 공개했으므로 두 수정이 포함된 버전을 설치하세요.
소스 코드 비교: 취약한 구현 vs 보안 패치
// 보안 패치 전 src/process_wrap.cc의 일부
node::Utf8Value file(env->isolate(), file_v);
options.file = *file;
// 배치 파일을 거부하지 않은 채 파일 이름을 uv_spawn()에 전달했습니다.
// CVE-2024-27980 업스트림 패치의 일부
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();
}
엔지니어링 및 시스템 보안 강화 체크리스트
- ✓
CVE-2024-27980및CVE-2024-36138수정이 포함된 지원 대상 Node.js 버전으로 업데이트하세요. - ✓외부 입력으로 batch 스크립트를 실행하지 말고, 검증된 인수로 실행 파일을 직접 호출하세요.
- ✓셸이 불가피하면 shell: true를 명령 실행으로 간주하고 엄격한 검증과 권한 확인을 적용하세요.
- ✓Windows 회귀 테스트에서
spawn()/spawnSync()와 batch 확장자를 확인하고 EINVAL로 안전하게 거부되는지 검증하세요.