R&D

CVE-2026-111497 node2shell 대응 가이드

Node.js Brotli 디코더 원격 코드 실행 취약점의 역할별 대응 방법, CVSS·CWE 정보, 영향 버전과 수정 버전, 원문 자료

This post is only available in Korean.

Read in English →
Contents
  1. 1역할별로 먼저 할 일
  2. 2CVE 상세
  3. 3Brotli와 node2shell, 쉽게 이해하기
  4. 4영향 버전 및 수정 버전
  5. 5원문 · 참고 자료

node2shell은 Node.js에 내장된 Brotli 압축 해제 디코더에서 발생한 원격 코드 실행(RCE) 취약점(CVE-2026-111497)입니다.
외부의 공격자가 로그인 없이 조작된 Brotli 압축 데이터만으로 Node.js 프로세스의 메모리를 오염시키고, 조건이 맞으면 임의의 코드를 실행할 수 있습니다.

역할별로 먼저 할 일

보안담당자

Node.js가 돌아가는 서비스부터 모두 찾으십시오. 결함은 npm 패키지가 아니라 Node.js 런타임에 포함된 Brotli 디코더에 있습니다. 패키지 목록(package.json)만 봐서는 드러나지 않으므로 서버, 컨테이너 이미지, 빌드 서버마다 실제 런타임 버전(node -v)을 확인해야 합니다.

우선순위는 외부 데이터가 Brotli로 풀리는 곳입니다. Content-Encoding: br 요청 본문을 해제하는 Express 5·body-parser 2 서비스, 공격자가 응답을 조작할 수 있는 외부 주소를 fetch()로 받아오는 서비스가 1순위입니다.

CISO

Node.js 프로젝트는 High, CVE를 발급한 Google은 CVSS 9.2 Critical로 평가했습니다. Imperva Red Team은 수정 직전 버전인 공식 Node.js 24.22.0 이미지(Linux arm64)에서 원격 코드 실행을 시연했습니다. 실제 공격 보고는 아직 없지만 EPSS는 상위 1.7%에 올라 있습니다.

지원이 끝난 20.x·23.x·25.x에는 패치가 나오지 않습니다. 이 버전을 쓰는 서비스는 업데이트가 아니라 지원 버전으로의 이전이 필요하므로 일정을 따로 잡아야 합니다. 어떤 서비스가 어떤 런타임 버전으로 돌아가는지 정리한 목록(SBOM)이 있어야 대응 속도가 나옵니다.

개발자

런타임 업그레이드가 유일한 완전한 조치입니다. Node.js 공식 공지에는 우회책이 없습니다. 22.x는 22.23.4, 24.x는 24.22.1, 26.x는 26.12.1 이상으로 올리고, Docker 베이스 이미지 태그와 .nvmrc, CI 러너의 Node.js 버전도 함께 바꾸십시오. 바꾼 뒤에는 프로세스를 반드시 재시작해야 새 런타임이 적용됩니다.

당장 올릴 수 없다면 리버스 프록시나 미들웨어에서 Content-Encoding: br 요청을 거부해 시간을 버십시오. 다만 이 방법은 fetch()로 받아오는 Brotli 응답까지는 막지 못합니다.

소규모 기업 · 외주 운영

영향 버전을 확인하고 패치하십시오. 웹사이트나 서비스를 맡긴 개발·운영 업체가 있다면 “Node.js를 22.23.4·24.22.1·26.12.1 이상으로 올렸는지, 올린 뒤 서비스를 재시작했는지”를 문의하시면 됩니다. 클라우드·호스팅 서비스를 쓰고 있다면 업체 공지를 먼저 확인하십시오.

Node.js 20 이하처럼 지원이 끝난 버전을 쓰고 있다면 패치가 나오지 않으므로, 지원 버전으로 옮기는 일정을 업체와 함께 잡으십시오.

CVE 상세

Node.js에 내장된 Brotli 디코더는 잘못된 블록 전환(block switch)을 영구적인 형식 오류가 아니라 입력이 더 필요한 일시적 상태로 처리했습니다. 그 결과 스트리밍 디코더가 8바이트짜리 내부 버퍼에 입력 바이트를 계속 덧붙여 버퍼 끝을 넘어 씁니다. 공격자가 node:zlib으로 해제되는 Brotli 데이터를 보낼 수 있으면 프로세스 메모리를 오염시켜 프로세스 종료, 메모리 노출, 원격코드실행(RCE)으로 이어질 수 있습니다.

위 설명은 Node.js 보안 공지 기준입니다.

CVE-2026-111497
심각도CRITICAL · CVSS · Google
CVSS9.2 CRITICAL
v4.0 · Google | v3.1 NVD 분석 전
CISA KEV미등재
악용 사실 확인 전 · 등재 시 패치 기한 부과
EPSS32.8%
상위 1.7% · 2026-10-25 산출
CWECWE-787 Out-of-bounds Write · 범위를 벗어난 메모리 쓰기
CWE-252 Unchecked Return Value · 반환값 확인 누락
공개2026-10-22
출처Google (CNA)
상태Awaiting Analysis

KEV · EPSS는 2026-10-26 13:19 KST 조회 기준이며 수시로 바뀝니다.

Brotli와 node2shell, 쉽게 이해하기

Brotli란?

Google이 만든 압축 방식입니다. gzip처럼 웹에서 데이터를 주고받을 때 크기를 줄이는 데 씁니다. Node.js는 이 압축을 푸는 코드(디코더)를 런타임 안에 직접 넣어 두었습니다.

무엇이 잘못됐나?

잘못된 데이터를 만나면 멈춰야 하는데, 디코더가 이를 “데이터가 아직 덜 왔다”로 착각했습니다. 그래서 8바이트짜리 작은 칸에 데이터를 계속 밀어 넣어 칸 밖까지 넘치게 씁니다. 작은 상자에 물건을 계속 밀어 넣어 옆 칸까지 쏟아지는 것과 같습니다.

왜 코드 실행까지 가나?

넘친 데이터가 옆 메모리를 덮어쓰면 프로세스가 죽거나, 메모리 내용이 새어 나가거나, 공격자가 심은 코드가 실행될 수 있습니다. 로그인은 필요 없습니다. 다만 앱이 그 데이터를 실제로 풀어야 공격이 성립합니다. Express 5·body-parser 2가 요청 본문을 풀 때, fetch()로 공격자 서버의 응답을 받을 때가 그 예입니다.

영향 버전 및 수정 버전

Node.js 런타임에 포함된 코드라서 npm 패키지 업데이트로는 고쳐지지 않습니다. 런타임 자체를 올려야 합니다.

릴리스 라인영향받는 범위수정 버전
26.x< 26.12.126.12.1
24.x< 24.22.124.22.1
22.x< 22.23.422.23.4
25.x · 23.x · 20.x 이하전 버전 (지원 종료)수정 없음 · 지원 버전으로 이전

원문 · 참고 자료

Z ZIEN
{# 쿠키 수집 안내 팝업 — 선택 전 방문자에게만(cookie-consent '쿠키 안내 팝업'). 버튼은 폼 POST 라 JS 없이 동작하고, 닫기(×)는 '거부' 와 같이 저장된다. source·close 는 누른 버튼별 집계용 — 닫기를 거부와 따로 센다(cookie-consent '쿠키 선택 집계'). #}