Node.js 보안 업데이트(2026년 10월): 제 블로그도 구버전이었습니다
사람이 직접 검수한 글 · 검수 검수 방식
Node.js 보안 업데이트는 쓰는 줄기에 맞춰 22.23.4, 24.22.1, 26.12.1 이상으로 올리면 됩니다. 확인해 보니 이 블로그의 배포 환경도 패치 전인 24.14.1로 고정돼 있었습니다. 24.22.1로 올려 같은 코드를 다시 빌드했더니 결과물 298개 파일이 한 바이트도 다르지 않았고, 빌드 시간은 8.00초에서 7.94초였습니다. 미룰 이유가 없는 업데이트입니다.
직접 해 본 결과
- 올린 뒤 결과물 24.14.1 vs 24.22.1, 파일 해시 비교
- 298개 모두 동일
- 빌드 시간 각 1회
- 8.00초 → 7.94초
- 찾은 구버전 고정 모두 저장소 1개의 복제본
- 6곳
이 글의 파일
이런 분께 / 준비물
이런 분께 맞습니다.
- AI 코딩 도구를 쓰려고 PC에 Node.js를 설치한 분
- AI로 웹사이트·업무 앱을 만들어 직접 배포하고 있는 분
- 외주로 받은 서비스가 Node.js로 돌아가는데, 업체에 무엇을 물어야 할지 모르는 분
준비물
- 명령 프롬프트나 PowerShell(Windows 기본). 설치할 프로그램은 없습니다.
1단계: 내 PC의 Node 버전 확인 (10초)
명령 프롬프트에 node -v를 입력하고, 나온 값을 아래 확인기에 넣습니다. 'node'은(는) 내부 또는 외부 명령...이 나오면 이 PC에는 Node가 없으니 2단계로 넘어갑니다.
Node.js 버전 확인기
기준: 패치 버전 22.23.4, 24.22.1, 26.12.1 (2026-10-21 공식 발표). 입력한 내용은 이 브라우저 안에서만 확인하며 어디에도 전송하지 않습니다.
- 20.x 이하와 홀수 버전(21, 23, 25)은 지원이 끝나 이번 패치가 나오지 않았습니다. 20.x는 2026년 4월 30일에 지원이 끝났습니다.
- 지금 새로 설치한다면 24.x(장기 지원, LTS)가 무난합니다. 24.x는 2028년 4월까지 지원됩니다.
2단계: PC보다 놓치기 쉬운 곳, 버전 고정 파일
PC의 Node만 올리면 끝나지 않습니다. 배포 서버나 자동 빌드는 저장소 안 설정 파일에 적힌 버전을 따로 내려받습니다. 이 블로그가 그랬습니다. PC와 같은 24.14.1이 .node-version 파일에 적혀 있었고, 배포할 때마다 그 버전이 쓰이고 있었습니다.
이런 파일을 폴더째 찾아 주는 스크립트를 만들었습니다. 파일을 읽기만 하고 아무것도 고치거나 보내지 않습니다. 내려받은 파일이 있는 폴더(보통 다운로드 폴더)에서 명령 프롬프트를 열고 실행합니다.
cd %USERPROFILE%\Downloads
node find-node-pins.mjs C:\내작업폴더
find-node-pins.mjs 내려받기 · 찾는 곳: .node-version, .nvmrc, .tool-versions, Dockerfile의 FROM node:, GitHub Actions의 node-version:, package.json
제 작업 폴더 전체(파일 67,710개)에 돌린 결과입니다. 4분 53초 걸렸습니다. 폴더가 크면 몇 분 걸릴 수 있습니다.
| 판정 | 곳 | 내용 |
|---|---|---|
| 업데이트 필요 | 6 | 모두 이 블로그 저장소의 .node-version(24.14.1). 원본 1곳 + 브랜치별 작업 폴더 5곳 |
| 범위(메이저만 지정) | 3 | 다른 프로젝트의 GitHub Actions node-version: 22 |
| 안전 | 1 | 24.22.1로 올린 작업 폴더 |
| 참고(engines) | 31 | package.json의 허용 범위. 실제 버전을 고정하지 않음 |
결과에서 두 가지를 배웠습니다.
- 구버전 6곳은 사실 1곳이었습니다. 브랜치마다 작업 폴더를 따로 두다 보니 같은 파일이 6벌 있었습니다. main에서 고쳐도 진행 중인 브랜치에는 옛 버전이 남으니, 그 브랜치를 배포하기 전에 main 변경을 가져와야 합니다.
- 정확히 고정할수록 손으로 올려야 합니다.
22처럼 메이저만 적은 3곳은 실행할 때마다 최신 22.x를 받으니 다음 실행부터 자동으로 패치됩니다.24.14.1처럼 정확히 적으면 매번 같은 결과를 얻는 대신, 보안 패치도 사람이 올려 줘야 합니다.
3단계: 올리기
- PC: nodejs.org에서 24.x LTS 설치 파일을 받아 덮어 설치합니다. 설치 후 새 명령 프롬프트에서
node -v로 다시 확인합니다. - 버전 고정 파일: 숫자를 패치 버전으로 바꾸고, 바꾸기 전과 후의 빌드 결과를 비교합니다. 이 블로그는
.node-version의24.14.1을24.22.1로 바꿨습니다. - Docker 이미지:
FROM node:24.22.1처럼 바꾸고 이미지를 다시 만듭니다. 이미 만든 이미지는 다시 만들기 전까지 옛 Node 그대로입니다. - 외주로 받은 서비스: 업체에 “서버의
node -v결과와, 이 버전을 언제 어떻게 올릴지”를 물어보세요. - 올린 뒤에는 운영 쪽에서 확인합니다. 내 PC의
node -v가 아니라, 서비스가 실제로 도는 서버나 배포 로그에 찍힌 버전이 기준입니다. 아래에서 이 블로그의 배포 로그로 확인한 화면을 보여 드립니다.
직접 해본 결과: 올려도 결과물은 그대로
같은 커밋을 Docker의 Node 24.14.1과 24.22.1에서 각각 설치부터 빌드까지 돌렸습니다.
| Node 24.14.1 (기존) | Node 24.22.1 (패치) | |
|---|---|---|
| 빌드 시간 | 8.00초 | 7.94초 |
| 결과물 파일 | 298개 | 298개, 해시 모두 같음 |
| 배포물 검사 | 통과, 경고 0건 | 통과, 경고 0건 |
다만 Docker 실험은 개발 PC에서 한 재현입니다. 정말 바뀌었는지는 실제 배포 환경의 로그로 확인해야 합니다. 아래는 이 블로그의 실제 배포(GitHub Actions) 로그에서 Node 버전 줄만 뽑은 화면입니다. 10월 27일 운영 빌드는 24.14.1로, 바꾼 뒤의 배포는 24.22.1로 돌았습니다.
이 결과를 확인하고 배포 환경을 24.22.1로 올렸습니다. 이 블로그는 정적 사이트라 방문자 요청을 Node가 처리하지 않습니다. 위험은 빌드 중 외부에서 받은 데이터를 다루는 단계에 한정되지만, 결과물이 같다면 올리지 않을 이유가 없습니다.
라이브러리 버전 표기만 보면 틀립니다
Node에 들어 있는 라이브러리 버전을 세 버전에서 직접 읽어 봤습니다(process.versions).
| 라이브러리 | 24.14.1 | 24.22.0 (패치 직전) | 24.22.1 (패치) |
|---|---|---|---|
| Brotli | 1.2.0 | 1.2.0 | 1.2.0 |
| OpenSSL | 3.5.5 | 3.5.8 | 3.5.9 |
| undici | 7.24.4 | 7.29.1 | 7.30.1 |
| c-ares | 1.34.6 | 1.34.8 | 1.34.9 |
Brotli 취약점을 고친 24.22.1도 Brotli 버전은 1.2.0으로 표기됩니다. Rapid7 정리에 따르면 원래 Brotli 라이브러리는 1.2.0 이상 1.2.1 미만이 취약 범위입니다. 라이브러리 이름표만 읽는 점검 도구라면 패치된 Node까지 ’취약’으로 볼 수 있습니다. 판단 기준은 Node 자체의 버전입니다.
같은 Brotli 취약점은 PHP에도 걸렸습니다. PHP는 10월 26일 Windows 빌드를 Brotli 1.2.1로 다시 만들어 8.4.27-1처럼 -1을 붙여 냈습니다. 하나의 압축 라이브러리가 두 생태계를 함께 흔든 셈입니다. 같은 주의 PHP 취약점은 PHP2Shell 조치 글에 정리했습니다.
이번 릴리스에서 높음(High) 등급 4건
| CVE | 무엇이 문제였나 | 영향 줄기 |
|---|---|---|
| CVE-2026-111497 | Brotli 압축 해제 중 범위 밖 쓰기(멈춤·메모리 노출·원격 코드 실행 가능) | 22 · 24 · 26 |
| CVE-2026-105483 | 전각 숫자로 쓴 IP 주소를 인증서 확인에서 IP로 알아보지 못함 | 24 · 26 |
| CVE-2026-106069 | 0127.0.0.1처럼 앞에 0이 붙은 IP를 인증서 확인과 운영체제가 다르게 해석 | 22 · 24 · 26 |
| CVE-2026-105482 | DNS 조회가 NUL 문자가 든 이름을 조용히 잘라 버림 | 22 · 24 · 26 |
주의할 점과 한계
--build-snapshot이나 단일 실행 파일(SEA)의 스냅샷 기능을 쓴다면 한 가지 더 볼 것이 있습니다. 난수 캐시가 스냅샷에 저장돼 값이 반복되는 문제(CVE-2026-106074)가 함께 고쳐졌습니다. 스냅샷을 다시 만들어야 하는지 공식 안내는 없지만, 패치된 Node로 다시 만드는 쪽이 안전합니다.- 빌드 비교와 버전 표기는 각 1회 측정입니다. 이 블로그 한 곳의 결과이므로 다른 프로젝트에서도 결과물이 같다는 보장은 아닙니다. 올린 뒤에는 각자 테스트를 돌려 보세요.
- 공격을 재현하지 않았습니다. 버전과 결과물만 비교했습니다.
- 사실 관계는 2026년 10월 28일 기준입니다.
직접 하기 어렵다면 맡겨 주세요
저는 현업 개발자이고 uriui.com에서 홈페이지·업무 시스템 개발 외주를 하고 있습니다. AI로 만든 앱이나 외주로 받은 서비스의 Node 버전 확인과 업데이트가 필요하면 남겨 주세요. 메일로 답장드립니다.
문의를 잘 받았습니다
주소로 답장드리겠습니다. 급하시면 [email protected]으로 메일 주셔도 됩니다.
근거와 출처
직접 해 본 근거
- 직접 측정 2026년 10월 28일 이 블로그의 같은 커밋을 Docker의 Node 24.14.1과 24.22.1에서 각각 설치·빌드해, 결과물 파일 298개(검색 색인 제외)의 해시와 빌드 시간을 비교했습니다.
- 직접 측정 같은 날 Docker로 Node 24.14.1·24.22.0·24.22.1을 띄워, 각 버전에 들어 있는 라이브러리(Brotli, OpenSSL, undici, c-ares) 버전 표기를 직접 읽었습니다.
- 실행 코드 폴더 안에서 Node 버전을 고정해 둔 파일을 찾아 판정하는 스크립트를 만들어, 제 PC의 작업 폴더 전체(파일 67,710개)에 실행했습니다. 프로젝트 이름은 빼고 결과 수만 적었습니다.
- 직접 캡처 이 블로그의 실제 배포(GitHub Actions) 로그에서 Node 버전 줄을 뽑은 화면과, Docker로 세 버전의 라이브러리 표기를 읽은 화면을 2026년 10월 28일 명령 프롬프트에서 직접 캡처했습니다.