경력·사례·글은 한국어 원문으로 제공됩니다.

← 모든 기록

기술 글 / 클라우드 운영

Node2Shell 대응기: Node.js 패치와 AWS Lambda 리전별 차이

Node2Shell에 대응하며 설치한 Node와 서비스가 실행하는 Node를 따로 확인했다. Lambda는 같은 Node 22라도 리전별 검증 결과가 달랐다. 확인한 실행본과 임시 조치, 남은 검증을 정리했다.

작업 2026.10

약 14분 소요6,441자

#2026-11-02 업데이트 — 기다리던 Lambda 패치 배포 완료

리전마다 결과가 달라 며칠 동안 확인을 이어갔는데, 이제 AWS의 패치 배포 완료를 확인했다. AWS 공식 보안 공지는 10월 30일(미국 태평양시간) 갱신본에서 Lambda Node.js 22·24·26의 ZIP 관리형 런타임에 보안 패치를 1·2단계까지 배포했다고 밝혔다. 새로 만들거나 수정한 함수뿐 아니라, 아직 업데이트를 받지 못한 기존 Auto 함수에 적용하는 단계도 끝났다는 뜻이다.

아래 기록에서는 버지니아의 검증 실행본을 미적용으로 취급했다. 이제는 AWS의 전체 배포 완료 공지를 기준으로, 버지니아도 공급자의 패치 배포를 기다리던 상태에서 벗어난 것으로 본다. 다만 버지니아의 개별 완료 시각이나 내 운영 함수의 현재 실행 버전을 이번에 직접 확인한 것은 아니다.

달라진 부분11월 2일에 확인한 상태
Lambda 관리형 런타임AWS가 보안 패치 1·2단계 배포 완료를 공지
버지니아AWS의 전체 배포 완료 공지를 근거로 판단. 개별 함수의 적용 여부는 실행 로그 확인 필요
임시 layer·wrapper이번 확인만으로 제거 완료로 바꾸지 않음. 실제 패치 런타임과 업무 동작을 확인한 뒤 정리할 대상

AWS 관리형 런타임의 적용 여부는 함수의 콜드 스타트 로그에 남는 INIT_START로 확인한다. AWS가 안내한 보안 패치 기준은 Node.js 22의 nodejs:22.mainline.v157 이상, Node.js 24의 nodejs:24.mainline.v114 이상이다. 특히 Node.js 24에는 먼저 수정을 백포트했기 때문에 process.version만으로 적용 여부를 판단하면 안 된다. 같은 공지의 24.22.2 전환 일정은 이번 보안 패치 배포 완료와 별도로 읽어야 한다.

임시 wrapper로 별도 Node를 실행한다면 INIT_START만으로는 부족하다. 서비스 프로세스의 process.execPath와 process.version, 해당 바이너리의 수정 근거를 따로 대조해야 한다.

Function update나 Manual 모드로 둔 함수, 컨테이너 이미지로 배포한 함수까지 모두 자동으로 끝난 것은 아니다. 설정에 따른 업데이트나 이미지 재빌드·재배포가 남을 수 있다. 내장 Node와 NAS 자체 패키지의 상태도 이번 AWS 공지로 완료 처리하지 않았다.

기다리던 관리형 런타임 패치 배포는 끝났다. 내 대응을 마무리하려면 실제 운영 함수의 적용 여부를 확인하고 임시 조치를 걷어낸 뒤 다시 검증해야 한다.

아래는 2026년 10월 26~28일 당시의 대응 기록이다. 리전별 표와 남은 작업도 그때의 상태로 남겨 둔다.


#터미널의 버전만으로는 답이 안 됐다

Node2Shell(CVE-2026-111497)에 대응하면서 먼저 node --version을 실행했다. 터미널의 결과만으로는 서비스도 그 Node를 쓰는지 알 수 없었다.

개발 도구는 자체 Node를 포함하고 있었고, NAS에는 컨테이너와 운영체제 패키지가 따로 있었다. Lambda 설정에는 nodejs22.x라고 적혀 있었지만 실제 패치 버전은 보이지 않았다.

설치 목록을 본 뒤 실행 중인 프로세스와 배포 파일을 확인했다. 작업 기록에도 설치, 설정 반영, 실제 실행 확인을 따로 적었다.

이때 필요한 정보는 Node.js의 process API에 있었다. process.version은 그 프로세스의 Node 버전, process.execPath는 실행 파일 경로, process.versions.brotli는 포함된 Brotli 버전을 보여준다. 확인할 항목을 코드로 줄이면 아래와 같다. 당시 로그를 복사한 출력이 아니라 진단 항목을 설명하는 예시다. Node.js process 문서

JS

({
  node: process.version,
  executable: process.execPath,
  brotli: process.versions.brotli,
  arch: process.arch,
});

이 값은 확인하려는 서비스 프로세스 안에서 읽어야 한다. 새 터미널에서 실행하면 그 터미널이 고른 Node의 정보가 나온다. Brotli 버전 문자열 하나도 수정 완료의 단독 근거로 삼지 않았다. 공식 수정 버전, 수정 표식과 회귀 결과, 실제 호출한 실행본을 함께 대조했다.

#어떤 입력이 문제였나

이번 취약점은 Node에 포함된 Brotli 압축 해제 코드에서 발생했다. 공격자가 제공한 잘못된 Brotli 데이터를 앱이 node:zlib로 해제하면 메모리가 손상돼 프로세스 종료, 정보 노출, 원격 코드 실행으로 이어질 수 있다. Node.js 보안 공지

외부 데이터를 어디서 압축 해제하는지 살폈다. 내 코드에 Brotli 호출이 없어도 외부 응답을 읽는 라이브러리가 있었다. 저장소의 코드와 배포된 실행본도 함께 봐야 했다. Node를 쓴다는 사실만으로 모든 서비스의 노출 조건이 같은 것은 아니었다.

아래는 그 대응 과정의 기록이다. 침해가 발생했다는 보고나 모든 공격 경로를 확인한 결과는 아니다.

#설치한 파일과 실행 중인 파일

Mac은 기본 Node를 24.22.1로 올린 뒤 재부팅 후 프로세스를 다시 확인했다. 이전 Brotli를 사용하는 프로세스가 확인 범위에 남아 있는지 보고, 재기동한 서비스의 응답과 연결 상태를 점검했다.

Ubuntu는 기본 Node를 22.23.4로 바꾸고 대상 서비스를 재시작했다. Windows는 26.12.1 설치 파일의 서명과 설치 결과를 확인한 뒤 관련 도구를 실행했다. 세 버전은 10월 보안 릴리스의 수정 버전이다. 공식 릴리스 목록

NAS의 n8n, Space, Node-RED 컨테이너는 업데이트 후 전달받은 버전·HTTP 응답·Brotli 회귀 결과를 대조했다. NAS 자체 패키지가 제공하는 Node는 따로 남았다. 컨테이너를 업데이트해도 그 패키지까지 바뀌지는 않았다.

데스크톱 앱의 내장 Node도 있었다. 기본 PATH의 Node를 바꿔도 앱에 포함된 바이너리는 그대로일 수 있었다. 내장 파일을 임의로 교체하지 않고 공식 수정본 확인을 기다리기로 했다.

#같은 Node 22도 리전마다 달랐다

Lambda의 nodejs22.x는 런타임 계열을 가리킨다. 개별 런타임 버전은 RuntimeVersionArn으로 식별하며 콘솔이나 초기화 로그에서 확인한다. AWS는 새 런타임을 리전별로 순차 배포한다. 같은 리전에서도 함수의 업데이트 시점에 따라 다른 버전을 받을 수 있다. Auto가 켜져 있어도 모든 함수가 동시에 패치되는 것은 아니다. AWS 런타임 업데이트 문서

실제 검증에서도 차이가 났다. 다음은 10월 27일 개발·격리 검증과 10월 28일 운영 설정 대조 기록이다. 서울·버지니아 외에 인도네시아·필리핀·브라질 환경의 검증도 포함했다. 국가 이름과 실제 배포 리전은 구분했다. 필리핀 환경의 시험은 싱가포르 리전에서 수행했다.

표의 판단은 확인한 개발·검증 실행본 기준이다. 수정 확인은 Brotli 수정 표식이 있었고, 미적용 취급은 표식이 없었다는 뜻이다. 운영 전체의 완료표는 아니다.

2026년 10월 28일(KST) 기준 · 10월 27~28일 검증 기록을 정리한 표이며, 운영 환경을 새로 재검사한 결과는 아니다.

환경 · 리전실행한 Node수정 여부
서울22.23.4수정 확인
버지니아22.23.2미적용 취급
인도네시아 · 자카르타22.23.4수정 확인
필리핀 · 싱가포르22.23.2미적용 취급
브라질 · 상파울루22.23.4수정 확인

어디까지 확인했는지는 환경마다 달랐다.

  • 서울 (ap-northeast-2): 임시 복제본에서 실행했다. 이후 해당 운영 ARN과 대조했으나 당시 운영의 직접 버전 출력은 확보하지 못했다.
  • 버지니아 (us-east-1): 임시 복제본에서 실행했다. 이후 해당 운영 ARN과 대조했으나 당시 운영의 직접 버전 출력과 패치 완료는 미확인이다.
  • 인도네시아 · 자카르타 (ap-southeast-3): 인증 개발 함수를 직접 실행했고 임시 복제본에서도 확인했다. 운영 전체를 검증한 결과는 아니다.
  • 필리핀 · 싱가포르 (ap-southeast-1): 외부 작업을 모의 처리한 임시 복제본에서 Node 22를 실행했다. 원래 운영 함수의 전환과 실제 스택 동작을 확인한 결과는 아니다.
  • 브라질 · 상파울루 (sa-east-1): 외부 작업을 모의 처리한 임시 복제본에서 Node 22를 실행했다. 원래 운영 함수의 전환과 실제 스택 동작을 확인한 결과는 아니다.

서울·자카르타·상파울루에서 수정 버전을 확인했다고 다른 리전까지 완료로 묶을 수는 없었다. 버지니아와 필리핀 환경의 싱가포르 검증 실행본은 패치 미적용으로 취급했지만, 두 리전의 모든 함수가 미적용이라고 단정하지는 않았다. 같은 국가의 서비스라도 다른 리전을 쓰는 함수가 있어 국가 전체의 완료표로 읽을 수도 없었다.

런타임 ARN이 같다는 것은 검증한 실행본과 연결할 근거다. 해당 운영 프로세스에서 버전과 실행 경로를 직접 읽은 결과와는 구분했다. 리전뿐 아니라 계정·아키텍처·함수별로 확인해야 했다.

오래된 런타임을 Node 22로 전환하거나 임시 실행 설정을 제거한 대상 중에는 호출 기록이 없는 함수도 있었다. 오류가 0이어도 호출이 없었다면 업무 동작을 확인한 것은 아니었다. 기록에는 런타임 전환, 자연 호출 관측, 보안 수정 확인을 각각 남겼다.

#임시 패치를 넣은 곳도 있었다

별도 서비스군에서는 관리형 런타임의 수정을 확인하기 전까지 공식 Node 22.23.4 바이너리를 임시 Lambda layer에 넣었다. layer는 함수에 파일을 제공하고, 시작 스크립트인 wrapper는 제공된 Node 바이너리를 실행하도록 연결했다. layer를 붙이는 설정과 그 바이너리로 실제 실행되는지는 따로 확인해야 했다. 기존 환경 변수와 layer는 보존하고, 바이너리는 공식 체크섬과 대조했다.

대상 함수들의 설정 반영은 확인했다. 패치 버전의 실행 로그는 호출된 웹·이미지 함수와 일부 보조 함수에서 확보했다. 호출하지 않은 함수는 설정 확인까지만 끝난 상태였다. 이미지 함수도 잘못된 입력 거부까지만 확인했으므로 실제 이미지 변환은 미검증으로 남겼다.

임시 바이너리는 특정 버전에 고정된다. 다음 Node 보안 수정은 따로 반영해야 하고, 정규 배포 때 임시 설정이 사라지지 않는지도 봐야 한다. 관리형 런타임에서 수정 버전을 확인한 뒤에는 임시 layer와 wrapper를 제거하고 다시 검증해야 한다.

#끝난 일과 남은 일

기록에 남긴 상태를 모으면 다음과 같다. 각 항목은 확인 시점과 대상이 다르다.

범위처리한 부분남은 부분
Mac·Ubuntu·Windows 대상 실행 환경수정 버전 설치와 대상 프로세스·서비스·도구 확인확인 대상 밖의 실행본까지 전수 검증한 것은 아님
NAS 컨테이너업데이트 후 전달받은 버전·응답·회귀 결과 대조고정 이미지 설정을 이용한 다음 재배포 시험
NAS 자체 패키지·Codex 내장 Node기본 Node·컨테이너와 별도로 분류공식 수정본 포함 여부 확인과 적용
임시 패치 대상 Lambda설정 반영과 호출된 함수의 패치 실행 로그 확인미호출 함수 검증, 관리형 수정 확인 후 임시 조치 제거
다른 Lambda 런타임 전환 대상전환·일부 임시 설정 제거, 일부 자연 호출 관측직접 실행 버전과 업무 검증. 리전별 차이는 위 표의 범위로 확인
외부 입력 제한 후보코드 준비마지막 확인인 10월 26일에는 운영 미적용. 저장 동작·배포 설정 연결도 남음

코드 준비와 운영 적용 사이에도 빈칸이 있었다. 그 상태를 완료로 바꾸면 다음에 확인할 대상이 기록에서 사라진다.

#배포 기록에 실행 버전을 더했다

이전에 배포 추적 기준을 정리하며 커밋, 빌드 결과물, 운영 버전, 복구 방법을 연결해 두기로 했다. 이번에는 거기에 실제 실행 환경을 붙였다.

배포한 결과물 → 리전·런타임 식별자 → 실행한 Node → 수정 근거와 호출 결과

버전 옆에 어느 리전의 어떤 실행본을 봤는지 적어 두니 다음 확인 대상도 분명해졌다. 호출하지 않은 함수, 임시 패치를 걷어낼 함수, 공급자의 수정본을 기다리는 앱이 각각 남았다.

작성 2026-11-03

2026년 10월 26~28일 대응 기록에 11월 2일 AWS 공식 공지 확인 내용을 추가했다. 리전별 표와 기존 본문은 당시 상태를 보존했다. 이번 편집에서 운영 환경을 새로 재검사하지 않았으며 계정·서비스 식별정보는 생략했다.