web-security

Next.js 보안 경보: CVE-2025-66478 취약점 분석 및 패치 가이드

지난 React2Shell(CVE-2025-55182) 이슈에 이어, 이를 상속받은 Next.js 전용 보안 취약점인 CVE-2025-66478이 발표되었습니다. 이 취약점 역시 **CVSS Score 10.0(Critical)**을 기록하며 전 세계 Next.js 메인테이너들을 긴장시켰습니다.

단순히 React의 문제를 넘어, Next.js의 App Router 구조와 Server Actions 구현 방식이 어떻게 공격의 매개체가 되었는지 시니어 개발자의 시각으로 해부해 보겠습니다.


목차


CVE-2025-66478: Next.js에서 왜 더 위험했나?

이 취약점은 앞서 발표된 React Server Components(RSC)의 역직렬화 문제를 Next.js의 특화된 인프라 환경에서 구체화한 것입니다. Next.js는 개발자 경험(DX)을 위해 서버와 클라이언트 사이의 통신을 고도로 추상화했는데, 이 과정에서 서버 측 실행 컨텍스트에 대한 검증 부족이 드러났습니다.

특히 클라이언트가 서버 액션(Server Actions)을 호출할 때 보내는 메타데이터를 조작하여, 서버 내부에 정의된 비공개 유틸리티 함수나 환경 변수에 접근할 수 있는 통로가 열렸다는 점이 치명적이었습니다.

Next.js Server Actions security advisory diagram showing the flow of a malicious request bypassing internal validation and leading to unintended function execution on the server.

취약점 메커니즘: 추상화된 서버 함수 호출의 허점

Next.js는 use server 지시어를 통해 정의된 함수를 빌드 타임에 고유한 ID로 매핑합니다. 공격자는 이 ID를 탈취하거나 추측한 뒤, RSC 프로토콜의 취약점을 이용하여 원래 호출되어서는 안 되는 서버 내부 함수를 강제로 실행시킬 수 있었습니다.

이 과정에서 서버는 클라이언트가 보내온 인자(Arguments)를 신뢰하여 역직렬화하고 실행하는데, 이때 공격자가 주입한 악성 객체가 서버의 Global Namespace를 오염시키거나 임의의 명령을 실행(RCE)하게 됩니다.

// 보안 취약점에 노출될 수 있는 코드 패턴 예시
// actions.ts
"use server";

// 이 함수는 내부적으로만 쓰이도록 설계되었으나, 
// 취약점이 있는 버전에서는 ID만 알면 외부에서 직접 호출이 가능했습니다.
export async function internalSystemTask(config: any) {
  // config 객체의 역직렬화 과정에서 악성 코드가 주입될 수 있음
  const result = await someProcess(config);
  return result;
}

공격 시나리오와 파급력

  1. ID 스캐닝: 공격자는 Next.js 앱의 정적 번들을 스캔하여 action-id 목록을 확보합니다.
  2. 페이로드 구성: RSC 역직렬화 취약점을 이용해 서버의 자바스크립트 엔진을 장악할 수 있는 특수 객체를 생성합니다.
  3. 엔드포인트 타격: 위조된 POST 요청을 /_next/data/... 또는 액션 엔드포인트로 전송합니다.
  4. 서버 장악: 서버는 해당 요청을 처리하며 공격자의 코드를 실행하고, 결과적으로 데이터베이스 커넥션 스트링 탈취, 환경 변수(.env) 노출 등의 피해가 발생합니다.

실무 보안 패치 및 대응 전략

가장 우선적인 조치는 프레임워크 업데이트입니다.

1. 긴급 버전 업데이트

  • Next.js 15.x: 15.0.7, 15.1.11 이상 (현재 최신 권장 버전 유지)
  • Next.js 14.x: 14.2.35 이상

2. 미들웨어를 통한 검증 (추가 방어선)

패치 이후에도 중요한 API나 액션에 대해서는 미들웨어 단계에서 Origin 체크Rate Limiting을 강화하는 것이 좋습니다.

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/request';

export function middleware(request: NextRequest) {
  // Server Action 호출 경로에 대한 출처 검증 강화 예시
  if (request.nextUrl.pathname.includes('/_next/action')) {
    const origin = request.headers.get('origin');
    if (origin !== process.env.ALLOWED_ORIGIN) {
      return new NextResponse(null, { status: 403 });
    }
  }
  return NextResponse.next();
}

개발자 팁: ‘use server’ 사용 시 주의사항

💡 시니어 개발자의 조언 서버 액션은 편리하지만, **“모든 서버 액션은 공용 API 엔드포인트와 같다”**는 사실을 명심해야 합니다. 내부 로직은 가급적 액션 내부가 아닌 별도의 서비스 계층으로 분리하고, 액션 함수 자체는 클라이언트에서 넘어온 데이터를 검증하는 ‘관문’ 역할에 집중하게 만드세요.


FAQ: 자주 묻는 질문

Q1. Next.js 13 버전(Pages Router)은 안전한가요?

CVE-2025-66478은 주로 App Router와 RSC 환경에 특화된 취약점입니다. 하지만 RSC의 근간인 React 패키지 자체가 취약하다면 Pages Router에서도 간접적인 영향이 있을 수 있으므로, 가능한 한 최신 보안 패치가 포함된 버전을 사용하는 것이 권장됩니다.

Q2. 로컬 개발 환경에서도 위험한가요?

네, 로컬에서 실행 중인 개발 서버도 네트워크 접근이 가능하다면 공격받을 수 있습니다. 특히 퍼블릭망에 연결된 개발 서버나 터널링 도구(ngrok 등)를 사용 중이라면 매우 위험합니다.

Q3. 패치 후에 기존 코드를 수정해야 하나요?

프레임워크 업데이트만으로 핵심 취약점은 해결됩니다. 다만, 이번 이슈를 계기로 Server Actions에 전달되는 인자의 타입 검증(Zod 등 활용) 로직이 누락되었다면 보완하는 것을 강력히 추천합니다.


마무리하며

마법 같은 기능을 제공하는 프레임워크일수록 그 내부 구현의 복잡성 속에 취약점이 숨어들기 쉽습니다. 이번 10점 등급 취약점은 우리에게 프론트엔드와 백엔드의 경계가 무너지는 시대에 **‘경계 보안’**이 얼마나 중요한지 다시금 깨닫게 해주었습니다.

자세한 기술 명세는 Next.js 공식 보안 어드바이저리에서 확인하세요.

이 글이 마음에 드셨나요?

로딩 중...