PHP 다음으로 주목받은 Node.js 취약점, 무엇이 위험할까?
압축 데이터를 풀다가 서버에서 코드가 실행될 수 있는 이유
PHP 보안 이슈와 함께 Node.js의 압축 해제 기능에서도 심각한 취약점이 공개됐다. 문제의 이름은 CVE-2026-111497이다.
공격자가 조작한 데이터를 프로그램이 압축 해제하면 메모리가 손상되고, 경우에 따라 프로그램 중단이나 정보 유출, 원격 코드 실행(RCE)으로 이어질 수 있다. 공식 위험도는 높음(High)이다. Node.js 공식 보안 공지
다만 “Node.js를 설치한 모든 서버가 접속만으로 해킹된다”는 뜻은 아니다. 어떤 데이터를 받아서 어떻게 처리하는지가 중요하다.
1. 먼저 알아둘 것: Node.js와 Brotli
Node.js는 무엇인가?
Node.js는 자바스크립트로 서버나 개발 도구를 실행할 수 있게 해주는 프로그램이다. 웹사이트 뒤에서 로그인 요청을 처리하거나, 다른 서버의 데이터를 가져오거나, 파일을 변환하는 데 사용된다.
Brotli는 무엇인가?
Brotli는 데이터를 작게 줄이는 압축 방식이다. 파일을 ZIP으로 묶어 용량을 줄이는 것과 목적이 비슷하다.
예를 들어 서버가 긴 문서를 압축해서 보내면 받는 쪽은 적은 데이터를 전송받고, 압축을 풀어 원래 내용을 읽는다. Node.js는 내장 모듈인 node:zlib를 통해 Brotli 압축과 압축 해제를 지원한다. Node.js 압축 모듈 문서

이번 문제가 발생한 곳은 이 흐름 중 압축을 푸는 부분이다.
2. 왜 압축을 푸는 일이 보안 문제가 될까?
데이터를 잠시 보관하는 공간, 버퍼
압축 해제 프로그램은 입력 데이터를 읽으며 “이 기호는 어떤 뜻인지”, “다음 데이터를 얼마나 읽어야 하는지”를 판단한다. 이때 계산 중인 데이터를 잠깐 보관하는 메모리 공간을 사용하는데, 이를 버퍼(buffer)라고 부른다.
버퍼를 정해진 칸 수만 가진 서랍이라고 생각하면 쉽다. 데이터를 넣을 공간이 끝났다면 멈추거나 오류를 내야 한다.
잘못된 데이터를 오류로 처리하지 못한 문제
이번 결함에서는 잘못된 압축 형식을 만났을 때, 프로그램이 이를 확실한 오류로 처리하지 않고 아직 입력이 부족하니 더 받아야 한다고 판단했다. 그 결과 내부 버퍼에 데이터가 계속 추가돼 경계를 넘어 쓸 수 있었다. 공식 취약점 설명

이런 문제를 경계 밖 쓰기(out-of-bounds write)라고 한다. 프로그램이 자기에게 허용된 메모리 범위를 벗어나 다른 공간까지 건드린다는 뜻이다.
단순히 파일을 잘못 읽는 데 그치지 않고 프로그램 자체의 동작이 흔들릴 수 있어 위험하다.
3. 메모리가 손상되면 어떤 일이 생길까?
가능한 결과는 크게 세 가지다.
| 프로그램 중단 | 서버 프로세스가 비정상 종료돼 요청을 처리하지 못한다. |
| 메모리 정보 유출 | 실행 중인 프로그램의 메모리 내용이 노출될 수 있다. |
| 원격 코드 실행 | 공격자가 의도한 코드가 서버 프로세스에서 실행될 수 있다. |
공식 공지는 이 세 가지 가능성을 명시한다. 다만 가능성이 있다는 설명과 실제 공격 성공은 구분해야 한다. 서버 환경과 입력 경로 등에 따라 결과가 달라지므로, 잘못된 데이터를 보내면 언제나 서버를 장악할 수 있다고 해석하면 안 된다. Node.js 공식 공지
원격 코드 실행 = 서버 관리자 권한 획득은 아니다.
피해 범위에는 해당 프로세스의 권한, 접근 가능한 파일과 인증 정보, 실행 환경의 격리 수준 등이 영향을 준다.
4. 어떤 서비스가 특히 확인해야 할까?
핵심 질문은 다음과 같다.
외부에서 받은 Brotli 데이터를 우리 Node.js 프로그램이 압축 해제하는가?
직접 압축 해제 코드를 작성했을 수도 있고, 사용하는 라이브러리가 대신 처리할 수도 있다. Node.js 문서에는 createBrotliDecompress(), brotliDecompress() 등의 API가 제공된다. 공식 API 문서
실무에서는 다음 경로를 점검할 수 있다. 아래는 노출 가능성을 살펴보기 위한 예시이며, 각 서비스가 자동으로 취약하다는 뜻은 아니다.
- 사용자가 올린 압축 데이터를 서버에서 풀어 읽는 기능
- 외부 API나 웹사이트에서 가져온 압축 응답을 처리하는 기능
- 데이터를 수집·변환하는 백그라운드 작업
- 외부 파일이나 데이터를 받아 처리하는 개발, 자동화 도구

예를 들어 정적 파일을 압축해서 내보낸다는 사실만으로 외부에서 받은 압축 데이터를 푸는 경로까지 존재한다고 단정할 수는 없다. 보내는 작업과 받는 작업을 구분해서 확인해야 한다.
5. 어느 버전으로 업데이트해야 할까?
이번 보안 수정이 포함된 버전은 다음과 같다.
| 사용 중인 버전 | 수정 버전 |
| Node.js 22.x | 22.23.4 |
| Node.js 24.x | 24.22.1 |
| Node.js 26.x | 26.12.1 |
같은 계열에서 위 버전 또는 이후의 보안 수정 버전을 적용하면 된다. 공식 릴리스 안내
이번 업데이트에는 Brotli 문제 외에도 DNS 처리, TLS 인증서 검증 등과 관련된 수정이 함께 포함됐다. Brotli 사용 여부를 확인하는 일과 별개로 런타임 업데이트를 진행할 이유가 있다. 공식 보안 공지
6. 개발자와 운영자는 어떻게 대응하면 될까?
① 실제 서비스가 사용하는 버전 확인
터미널에서는 다음 명령으로 확인할 수 있다.
node --version
다만 개발자 노트북에서 확인한 버전이 운영 서버의 버전과 같다는 보장은 없다. 서버, 컨테이너, 배포 플랫폼 등 실제로 프로그램이 실행되는 환경을 확인해야 한다.
② Node.js 런타임 업데이트
여기서 혼동하기 쉬운 명령이 있다.
npm update
이 명령은 프로젝트 의존성을 갱신하는 데 사용된다. 이번 대응에서는 Node.js 실행 파일 자체의 버전을 바꿔야 한다.
설치 방식에 따라 버전 관리 도구, 운영체제 패키지, 컨테이너 이미지 또는 호스팅 플랫폼 설정에서 업데이트한다.
③ 서비스 재배포 또는 재시작
업데이트한 실행 파일을 서비스가 실제로 사용하도록 프로세스를 새로 시작해야 한다. 여러 서버나 컨테이너를 운영한다면 일부 인스턴스만 이전 버전에 남아 있지 않은지도 확인한다.
④ 압축 데이터를 처리하는 기능 확인
배포 후에는 외부 응답 수신, 파일 업로드, 데이터 가져오기처럼 압축 해제와 관련된 기능이 정상 동작하는지 점검한다. 오류율과 비정상 종료도 함께 살펴보면 좋다.
업데이트 전까지 입력 경로를 제한하는 방법을 검토할 수는 있지만, 특정 차단 규칙만으로 수정 버전 적용을 대신했다고 판단해서는 안 된다.
7. 일반 이용자도 무언가 해야 할까?
웹사이트를 방문하는 이용자라면 해당 서버의 Node.js를 직접 업데이트할 수는 없다. 서비스 운영자가 처리해야 한다.
반면 Node.js로 개인 서버나 자동화 프로그램을 실행하고 있다면 직접 확인할 대상이다. 회사에서 사용하는 완제품에 Node.js가 내장돼 있다면, 공급업체의 업데이트 안내를 확인하는 편이 적절하다.
이번 사건에서 기억할 핵심은 압축 데이터도 프로그램이 해석하는 외부 입력이라는 점이다. 로그인 정보나 검색어만 검사한다고 입력 보안이 끝나는 것은 아니다. 압축을 풀고, 파일 형식을 읽고, 외부 응답을 해석하는 과정에서도 취약점이 발생할 수 있다.
운영 중인 서비스가 있다면 우선 실행 중인 Node.js 버전을 확인하고 수정 버전을 배포하는 것부터 시작하면 된다.