2026년 11월 11일, Node.js 20용 업데이트는 제공되지 않습니다. 이번 보안 릴리스는 26.x, 24.x, 22.x만을 대상으로 합니다. Node.js 20이 2026년 4월 30일부로 공식 수명 주기(End-of-Life, EOL)를 마쳤기 때문입니다. 마지막 패치 빌드는 3월 24일에 배포된 20.20.2였고, 그 이후 33개의 CVE(보안 취약점)가 발표되었지만 20.x용 패치는 단 하나도 나오지 않았습니다. 이번 주 안으로 Node.js 24 또는 26으로 업그레이드하세요.

지금 Apidog을 사용해 보세요

이 CVE들은 Node.js 20이 제외된 채 진행된 최근 세 차례의 보안 릴리스를 통해 발표되었습니다. 불과 며칠 뒤면 네 번째 보안 릴리스가 예정되어 있으며, 사전 공지에 따르면 지원 대상인 모든 버전 라인에서 가장 심각한 취약점 등급이 'HIGH'로 평가되었습니다.

11월 11일 릴리스 일정과 Node.js 20이 제외된 이유

Node.js 프로젝트 팀은 2026년 11월 11일 수요일(또는 그 직후)에 26.x, 24.x, 22.x의 새로운 빌드를 배포할 예정입니다. 취약점 빌드가 정식 릴리스되기 전까지는 세부 CVE 정보가 공개되지 않습니다. 런타임 현황 점검 및 패치 당일 적용 명령어는 11월 릴리스 카운트다운 가이드에서 자세히 다루고 있으므로 이 글에서는 생략합니다.

Node.js 20이 목록에서 빠진 이유는 이미 유지보수가 종료되었기 때문입니다. 공식 수명 종료(EOL) 안내 페이지에는 다음과 같이 명시되어 있습니다. "새로운 보안 릴리스를 통해 문제가 발견되더라도, 동일한 취약점이 지원 종료(EOL) 버전에 영향을 미치는 경우 해당 버전을 위한 신규 릴리스는 제공되지 않습니다."

보안 권고문에는 반드시 주의 깊게 봐야 할 문장이 하나 더 있습니다. "보안 릴리스가 발행될 때, 수명이 종료된(EOL) 버전은 언제나 취약점의 영향을 받습니다."

Node.js 20이 이미 놓친 보안 패치들

Node.js 20 지원이 종료된 이후 이미 세 번의 보안 릴리스가 배포되었으나, 20.x용 빌드는 전혀 제공되지 않았습니다.

보안 권고 CVE 수 High Medium Low 수정 버전
2026년 6월 18일 12 2 6 4 26.3.1, 24.17.0, 22.23.0
2026년 7월 29일 11 3 5 3 26.5.1, 24.18.1, 22.23.2
2026년 10월 21일 10 4 3 3 26.12.1, 24.22.1, 22.23.4
총합 33 9 14 10 20.x 빌드 없음

이번 패치들이 다루는 코드는 API 서버가 상시 실행하는 핵심 영역입니다.

  • TLS 호스트명 검증: 6월과 10월 릴리스 모두에서 잘못된 호스트에 대한 인증서를 정상으로 수락하던 문제가 해결되었습니다.
  • HTTP/2: 7월의 고위험군 패치에는 힙 UAF(Use-After-Free) 및 원격 메모리 고갈 취약점 해결이 포함되었습니다.
  • DNS: 10월에는 dns.resolve*()가 NUL 바이트에서 호스트명을 잘라내어 허용 목록(Allowlist) 검증을 우회할 수 있던 문제가 수정되었습니다.
  • 압축: 10월 릴리스에서 원격 코드 실행(RCE)으로 이어질 수 있는 Brotli 디코더의 범위를 벗어난 쓰기(Out-of-bounds write) 결함이 해결되었습니다. 자세한 내용은 Brotli RCE 분석 글에서 확인할 수 있습니다.

이 목록을 주의 깊게 살펴야 합니다. 프로젝트 측에서는 지원 종료된 버전 라인을 별도로 평가하지 않으므로, 보안 권고문에는 현재 공식 지원 중인 버전만 명시됩니다. 물론 이러한 버그 중 일부는 20 버전에 아예 없는 코드에서 발생한 것일 수도 있습니다. 실제로 10월의 한 CVE는 프로젝트 측이 26.x 및 24.x에만 국한된 회귀 버그로 분류하기도 했습니다. 따라서 Node.js 20 기준에서 각 CVE의 현주소는 '패치되지 않았으며 위험도조차 평가되지 않은 상태'입니다. 안전하다고 보장해 준 사람도 없으며, 앞으로 확인해 줄 사람도 없습니다.

버그들이 서로 연계되어 공격으로 이어질 수 있다는 점(Bug chain)은 문제를 더욱 심각하게 만듭니다. 10월의 DNS 수정 사항은 6월의 패치를 보완한 것이며, 7월의 패치 역시 6월의 다른 수정을 완성한 것입니다. 이후에 나오는 모든 패치는 사용자가 현재 적용받지 못한 패치 위에 쌓여 올라갑니다.

Node.js 20 타임라인: 2026년 3월 24일 마지막 빌드 배포, 4월 30일 지원 종료(EOL), 이후 6월 18일, 7월 29일, 10월 21일 보안 릴리스에서 20.x 패치 누락, 그리고 예정된 11월 11일 릴리스

"하지만 아직 잘 동작하는데요"

맞습니다. 바로 그 점이 문제입니다.

수명이 다한 런타임이라고 해서 즉시 에러를 내며 멈추지는 않습니다. node -v를 입력하면 버전 번호가 그대로 출력되고, 테스트 통과 알림이 뜨며, 모니터링 대시보드도 정상(녹색)을 유지합니다. 하지만 진짜 위험은 미처 모니터링하지 못하는 곳에서 발생합니다.

  • 패치 내역 자체가 공격자의 지도가 됩니다. 보안 패치, 권고문, 커밋 로그는 동시에 공개됩니다. 공격자라면 누구나 지원 버전에서 변경된 내용을 분석해 동일한 취약 코드가 20 버전에도 남아 있는지 손쉽게 확인할 수 있습니다.
  • 사용 중인 클라우드 플랫폼에서 배포가 계속 허용될 수 있습니다. AWS Lambda는 2026년 4월 30일에 nodejs20.x를 지원 중단(deprecated)으로 분류했지만, 신규 함수 생성을 차단하는 시점은 2027년 7월 29일이며 기존 함수 업데이트 차단은 2027년 8월 31일까지 미뤄져 있습니다.
  • 생태계 패키지와 보안 감사는 계속 앞으로 나아갑니다. Node.js 프로젝트 팀은 주요 오픈소스 패키지들이 점차 EOL 버전에 대한 지원을 중단하며, 수많은 업계 컴플라이언스 및 보안 감사에서 유지보수가 중단된 런타임 사용을 금지하고 있다고 경고합니다.

업그레이드 대상 선택: 22가 아닌 Node.js 24 또는 26

가장 빠르고 안정적인 마이그레이션이 필요하다면 이번 주에 24로 전환하세요. 변경 및 제거된 기능을 감당할 여유가 있고 장기적인 지원 기간을 확보하고 싶다면 26을 선택하세요. 22는 건너뛰는 것이 좋습니다. 비록 11월 패치는 지원되지만, 6개월도 채 남지 않은 2027년 4월 30일에 수명이 종료되므로 내년 봄에 똑같은 마이그레이션 작업을 다시 반복해야 합니다.

버전 라인 상태 11월 5일 기준 최신 버전 지원 종료일 권장 대상
26.x “Lithium” Active LTS (2026년 10월 28일부터) 26.13.0 2029년 4월 30일 현재 서비스 전체를 철저히 재검증할 수 있는 환경
24.x “Krypton” Maintenance LTS (2026년 10월 20일부터) 24.22.2 2028년 4월 30일 20 버전에서 벗어나는 가장 빠르고 안전한 경로
22.x “Jod” Maintenance LTS 22.23.4 2027년 4월 30일 현재 시점에서 마이그레이션할 실익 없음

상기 일정은 Node.js 공식 릴리스 스케줄을 기반으로 합니다. 전환을 결정하기 전에 운영 플랫폼의 지원 여부를 먼저 확인하세요. 예를 들어 AWS Lambda의 경우 Node.js 26 런타임이 현재 퍼블릭 프리뷰 상태로 Lambda SLA 보장 대상이 아니므로, 프로덕션 환경에서는 24를 선택하는 것이 현재로서는 더 안전합니다.

2026년 11월 기준 Node.js 지원 기간 막대 차트: 22.x는 2027년 4월 30일 종료, 24.x는 2028년 4월 30일 종료, 26.x는 2029년 4월 30일 종료

마이그레이션 단계 및 주의해야 할 변경 사항

아래 표의 모든 내용은 22.0.0, 24.0.0, 25.0.0, 26.0.0 공식 릴리스 노트와 v22 to v24 마이그레이션 가이드를 정리한 것입니다. 전체 변경 사항 중 API 서비스에 직접 영향을 미치는 핵심 항목만 선별했습니다.

도입 버전 주요 변경 사항 영향을 받는 영역
22 import ... assert { type: 'json' } 제거, with 사용 필수 JSON을 import하는 ESM 코드
22 crypto.createCipher() 및 createDecipher() 제거 레거시 암호화 코드
23 및 24 사전 빌드된 32비트 Windows 및 32비트 armv7 Linux 바이너리 미제공, macOS 13.5 이상 필수 구형 호스트 머신 및 엣지 장비
24 OpenSSL 3.5 보안 레벨 2 적용: 2048비트 미만 RSA/DSA/DH 키, 224비트 미만 ECC 키, RC4 알고리즘 사용 금지 mTLS 통신 및 구형 업스트림 연동
24 tls.createSecurePair 제거, url.parse() 런타임 지원 중단(deprecated) 레거시 네트워킹 코드
24 엄격한 fetch() 규격 준수, AbortSignal 유효성 검사 강화, 스트림 및 파이프 오류 발생 시 throw 처리 HTTP 클라이언트, 프록시 로직
24 V8 13.6 탑재, 네이티브 애드온 컴파일 시 C++20 요구 가능성 있음 네이티브 C/C++ 모듈
25 (26 버전 목표 시) SlowBuffer 및 fs.F_OK, R_OK, W_OK, X_OK 제거, Corepack 기본 번들 제외 구형 유틸리티, Corepack 기반 Yarn/pnpm 환경
25 (26 버전 목표 시) IP 주소를 TLS servername으로 사용하는 방식 완전 지원 종료(EOL) IP 주소로 직접 연결하는 클라이언트
26 _stream_* 내부 모듈 및 writeHeader() 제거, module.register() 런타임 지원 중단(deprecated), Undici 8 탑재 구형 스트림 구현체, 커스텀 모듈 로더

이 중 OpenSSL 관련 변경점은 소스 코드에 직접 드러나지 않아 가장 까다로운 부분입니다. 애플리케이션 코드는 그대로인데, 구형 파트너 시스템과의 핸드셰이크가 런타임에서 갑자기 실패할 수 있습니다.

작업 브랜치를 생성한 후 .nvmrc, engines 필드, Dockerfile, CI 설정을 대상 버전에 맞게 수정하세요(새 환경 구성은 Node.js 설치 가이드를 참고하세요). 이후 네이티브 모듈이 새로 빌드되도록 패키지를 재설치하고, 제거된 API를 검색한 뒤, 공식 codemod를 실행하고 지원 중단 추적 옵션을 켠 상태로 서비스를 시작합니다.

nvm install 24 && nvm use 24 rm -rf node_modules && npm ci grep -rnE "assert \{ *type|createCipher\(|createDecipher\(|url\.parse\(|fs\.[FRWX]_OK|SlowBuffer|createSecurePair|_stream_[a-z]+|module\.register\(" \ --include="*.js" --include="*.mjs" --include="*.ts" --exclude-dir=node_modules . npx codemod run @nodejs/import-assertions-to-attributes npx codemod run @nodejs/crypto-createcipheriv-migration npx codemod run @nodejs/tls-create-secure-pair-to-tls-socket npx codemod run @nodejs/fs-access-mode-constants NODE_OPTIONS="--trace-deprecation" npm start 

codemod 적용 결과는 반드시 육안으로 직접 검토해야 합니다. 특히 createCipher의 경우, 변환된 코드는 구형 API로 암호화된 기존 데이터를 복호화할 수 없으므로 관련 데이터가 있다면 반드시 데이터 마이그레이션 계획을 병행해야 합니다.

Node.js 공식 사이트에는 아직 24에서 26으로의 마이그레이션 가이드가 제공되지 않으므로, 26으로 이동할 때는 25.0.0 및 26.0.0 릴리스 노트를 확인하시기 바랍니다.

새 버전에서 API가 동일하게 작동하는지 검증하기

단위 테스트(Unit test)만으로는 새로워진 TLS 스택과 HTTP 클라이언트가 실제 트래픽 환경에서 어떻게 동작할지 온전히 파악하기 어렵습니다. 메이저 버전을 2단계나 3단계 건너뛸 때는 실제 구동 중인 서비스의 전후 동작을 철저히 비교해야 하며, 이 작업은 코딩 에이전트를 활용하기에 적합합니다.

Apidog CLI를 사용하면 터미널에서 Claude Code, Codex, Cursor 등의 도구를 통해 Apidog 테스트 스위트를 바로 실행할 수 있습니다. 초기 설정은 다음과 같습니다.

npm install -g apidog-cli@latest apidog login --with-token <YOUR_TOKEN> npx -y skills add https://apidog.com # 안내에 따라 에이전트 선택 

설치 후 에이전트에 다음과 같은 프롬프트를 전달합니다.

My service runs on Node.js 20 in staging. Run Apidog test suite <suiteId> in project <projectId> against environment <envId> and save reports to reports/node20. When I redeploy on Node.js 24, run the same suite into reports/node24. List every request whose status, body, or TLS behavior changed. Then read the service logs for deprecation warnings and check each failure against the 22, 24, and 25 release notes: removed APIs, changed defaults, stricter fetch and AbortSignal handling, OpenSSL key size rejections. 

에이전트는 마이그레이션 전후 환경을 대상으로 동일한 테스트 스위트를 실행합니다.

apidog run --test-suite <suiteId> --project <projectId> -e <envId> \ -r cli,junit --out-dir reports/node20 # 서비스 대상 버전으로 재배포 및 재시작 apidog run --test-suite <suiteId> --project <projectId> -e <envId> \ -r cli,junit --out-dir reports/node24 

비교 검증의 신뢰성을 확보하기 위해 다음 두 가지 원칙을 지켜야 합니다.

  • 절대로 -k 옵션을 주지 마세요. 이 플래그는 SSL 인증서 유효성 검사를 비활성화하므로, 마이그레이션 과정에서 반드시 잡아내야 할 TLS 관련 결함을 감춰버립니다.
  • 외부 업스트림 호출 구간을 반드시 테스트에 포함하세요. OpenSSL 규격 강화로 인한 거부는 구형 파트너 시스템과 연동되는 엔드포인트에서 API 에러 형태로 발생하므로, 단순 /health 체크뿐만 아니라 외부 연동 경로 전체를 테스트해야 합니다.

마이그레이션 검증을 통과한 후에는 지속적인 안전을 위해 해당 테스트 라인을 파이프라인에 그대로 유지하세요. 워크플로우 구성은 Apidog CLI CI/CD 가이드를, 에이전트 설정은 Claude Code 연동 가이드를 참고하시기 바랍니다.

이번 주 당장 업그레이드할 수 없는 경우

상용 패치 빌드를 구매하세요. Node.js 수명 종료(EOL) 안내 페이지에서는 OpenJS 생태계 지속가능성 프로그램을 통해 협력 중인 3개 파트너사를 안내하고 있습니다. HeroDevs는 보안 패치가 포함된 NES(Never-Ending Support)를 제공하며, TuxCare의 ELS(Endless Lifecycle Support)는 EOL 버전용 수정 사항을 백포팅해 줍니다. NodeSource는 업그레이드 진단 및 지원 서비스를 제공합니다. 공식 프로젝트에서도 이를 임시방편이라고 명시하고 있으며, 실제로도 그렇습니다.

프로세스에 유입되는 트래픽 노출 범위를 최소화하세요. 다음 조치는 앞서 언급한 결함 유형에 노출되는 위험을 줄여주지만, 취약점 자체를 해결하는 것은 아닙니다.

  • 유지보수가 지속되는 프록시나 로드 밸런서에서 TLS 및 HTTP/2 처리를 대신 끝내고, 내부 프라이빗 네트워크를 통해 Node.js와는 일반 HTTP/1.1로만 통신하도록 구성합니다.
  • 인바운드 요청 및 외부에서 가져오는 콘텐츠 모두에서 신뢰할 수 없는 출처의 Brotli 압축 해제 작업을 전면 중단합니다.
  • 허용 목록 검사나 외부 호출을 진행하기 전에, NUL 바이트가 포함되었거나 비표준 IP 형식으로 표현된 호스트명을 원천 차단합니다.
  • 최소 권한 자격 증명 부여, 아웃바운드 트래픽 제한, 보안 패치가 적용된 타 서비스와의 시크릿 공유 금지 등을 통해 서비스를 철저히 격리합니다.

위험 요소를 문서화하고 공문화하세요. '임시 대증 요법'이 끝없이 이어지지 않도록 책임자, 최종 마이그레이션 기한, 보완 통제 조치를 명확히 문서로 남겨두어야 합니다.

자주 묻는 질문 (FAQ)

Node.js 20은 현재 지원을 받을 수 있나요? 아니요. 2026년 4월 30일부로 공식 지원이 종료(EOL)되었습니다. 마지막 릴리스는 2026년 3월 24일에 배포된 20.20.2이며, 프로젝트 차원의 추가 빌드 배포는 없습니다.

Node.js 20도 11월 11일에 발표되는 취약점의 영향을 받나요? 아직 CVE 세부 사항이 외부에 공개되지 않았으므로 정확히 어떤 취약점이 해당하는지는 단정할 수 없습니다. 다만 공식 가이드라인에 따르면 보안 릴리스 배포 시 EOL 버전은 항상 취약점의 영향을 받으며, 프로젝트 측에서 EOL 버전을 개별적으로 점검해 주지 않습니다.

Node.js 22로 업그레이드하는 것은 어떤가요? 추천하지 않습니다. 변경 폭이 가장 적어 보일 수 있으나, 22 역시 2027년 4월 30일에 지원이 종료됩니다. 24로 넘어가면 1년의 추가 지원 기간을, 26으로 넘어가면 2년의 추가 지원 기간을 확보할 수 있습니다.

Node.js 24와 26 중 어느 쪽을 선택해야 하나요? 이번 주 안에 즉시 전환해야 하거나 사용 중인 인프라 플랫폼이 아직 26을 완벽히 지원하지 않는다면 24를 선택하세요. 서비스 전체를 철저히 재검증할 여력이 있다면 2029년 4월 30일까지 장기 지원되는 26을 권장합니다.

현재 Node.js 25를 사용 중인데 이번 내용과 관련이 있나요? 네, 관련이 있습니다. Node.js 25는 2026년 6월 1일에 25.9.0 빌드를 끝으로 이미 지원이 종료되었습니다. 25 역시 이번 11월 보안 패치를 받지 못하므로 메이저 한 단계 상위인 26으로 마이그레이션해야 합니다.