SK쉴더스 로고
ADT캡스캡스홈
SK쉴더스

Vercel, Next.js use cache 함수 미인증 RCE 결함 공개

EQST Now | 2026.10.16

NOW Briefing

Brief 1 Next.js 16의 use cache 캐시 함수에서 인증 없이 원격 코드 실행(RCE)이 가능한 취약점이 공개됐습니다.
Brief 2 App Router에서 Cache Components를 켜고 use cache 함수가 타입배열 둘 이상과 공격자 제어 값을 함께 전송하면 사용자 조작 없이 서버 코드가 실행될 수 있습니다.
Brief 3 임시 대응책이 없으므로 Next.js 16.4.1로 업그레이드하고, React 서버 컴포넌트 패키지 버전도 함께 올려야 합니다.

‍

Vercel, Next.js use cache 함수 미인증 RCE 결함 공개

‍

■ 개요

‍

Next.js는 React 기반 웹 애플리케이션 프레임워크입니다. 2026년 10월 14일 Vercel은 정기 릴리스 일정 외 긴급 업데이트로 Next.js 16.4.1과 15.5.28을 배포하고, 인증 없이 원격 코드 실행이 가능한 취약점을 공개했습니다. 취약점이 발견된 Cache Components는 서버 렌더링 결과를 캐시하는 기본 비활성(옵트인) 기능입니다. 이 취약점에는 CVE가 할당되지 않았고, Next.js와 React 양쪽의 GitHub 보안 권고(GHSA-673q-mjm6-r5xr, GHSA-xqc2-xf4c-x3h3)로만 공개됐습니다.

권고가 밝힌 영향 조건은 App Router와 Cache Components를 사용하는 애플리케이션 중에서, use cache 지시어를 붙인 함수가 타입배열을 둘 이상 반환하는 경우입니다. use cache는 함수 결과를 캐시하도록 표시하는 지시어이며, 타입배열은 이진 데이터를 바이트 단위로 담는 자바스크립트 객체입니다. 이 조건에서 공격자가 제어하는 값이 함께 전송되면 인증이나 사용자 조작 없이 서버에서 코드가 실행될 수 있습니다. Vercel은 적용 가능한 임시 대응책이 없다고 밝혔습니다.

두 프로젝트 모두 이 취약점을 가장 높은 심각도로 분류했습니다. 근본 원인은 Next.js가 아니라 React 서버 컴포넌트(서버에서 렌더링한 결과만 브라우저로 보내는 구성 요소)의 전송 계층에 있습니다. 따라서 Next.js를 쓰지 않더라도 해당 React 패키지의 영향 버전(19.0.0~19.0.8, 19.1.0~19.1.9, 19.2.0~19.2.8, 19.3.0)을 사용하는 프레임워크와 번들러는 같은 영향을 받습니다. 현재까지 실제 공격에 악용된 사례나 공개 PoC는 보고되지 않았지만, 수정 커밋이 공개 저장소에 올라와 있어 취약점이 수정된 코드 지점은 외부에서 확인할 수 있습니다.

‍

■ 요약

‍

항목 내용
식별자 CVE 미할당, Next.js·React 보안 권고로만 공개됨
심각도 CVSS v4.0 9.5
취약점 유형 공식 CWE 미지정, React 서버 컴포넌트 전송 계층의 데이터 처리 결함에 따른 원격 코드 실행
영향/위험 • 인증·사용자 조작 없이 서버 코드 실행 가능
• 근본 원인이 React 서버 컴포넌트 전송 계층이어서 Next.js 외 React 서버 컴포넌트 지원 프레임워크·번들러도 같은 영향
• 제시된 우회책 없음
• 실제 악용·공개 PoC는 현재까지 미확인
취약 버전 • Next.js 16.0.0 ~ 16.4.0
• react-server-dom-webpack 19.0.0~19.0.8, 19.1.0~19.1.9, 19.2.0~19.2.8, 19.3.0
• react-server-dom-parcel 19.0.0~19.0.8, 19.1.0~19.1.9, 19.2.0~19.2.8, 19.3.0
• react-server-dom-turbopack 19.0.0~19.0.8, 19.1.0~19.1.9, 19.2.0~19.2.8, 19.3.0
벤더 대응 현황 • Next.js 16.4.1 배포(2026-10-14)
• React 19.0.9 / 19.1.10 / 19.2.9 / 19.3.1 배포(2026-10-14)
• 우회책 없음, 업그레이드만 안내됨

‍

■ 영향받는 구성과 조건

‍

use cache는 Next.js 15.0.0에서 실험 기능으로 도입된 뒤 16.0.0에서 정식 기능이 됐습니다. 동작하려면 Next.js 설정 파일 next.config.ts 또는 next.config.js에서 cacheComponents 옵션을 켜야 합니다. 공식 문서는 타입배열과 ArrayBuffer를 캐시 함수의 반환 가능 타입으로 명시하고 있어, 이진 데이터를 캐시하는 코드 자체는 문서화된 사용 패턴입니다. 다만 React 권고는 이 취약점이 "응답이 여러 타입배열과 공격자 제어 값을 함께 전송하는 극히 드문 경우"에만 해당한다고 설명합니다.

GitHub 보안 권고에 기재된 Next.js 영향 범위는 16.0.0부터 16.4.0까지이며, 15 계열은 여기에 포함되지 않습니다. Pages Router만 사용하거나 Cache Components를 켜지 않은 애플리케이션도 영향 범위에서 벗어납니다. 그럼에도 Vercel은 해당 패턴의 함수가 없는 애플리케이션까지 즉시 업그레이드할 것을 권고했습니다.

Next.js를 거치지 않고 React 서버 컴포넌트를 직접 사용하는 환경에서는 react-server-dom-webpack, react-server-dom-parcel, react-server-dom-turbopack 세 패키지가 영향 범위이며, 모두 19.0.0~19.0.8, 19.1.0~19.1.9, 19.2.0~19.2.8, 19.3.0 버전이 해당합니다.

⚠️ WARN

설정 변경이나 입력 필터링으로 이 취약점을 차단하는 방법은 공개되지 않았습니다.
버전 업그레이드로 대응해야 합니다.

‍

■ 패치로 본 결함 지점

‍

React는 Flight(서버와 클라이언트가 렌더링 데이터를 주고받을 때 쓰는 React 내부 전송 포맷)의 클라이언트 측 처리 코드를 수정했습니다. 두 권고 모두 취약점의 동작 원리를 구체적으로 공개하지 않아, 남은 단서는 React 19.3.1 릴리스에 포함된 수정 커밋([19.3.x][Flight] Improve transport protocol)뿐입니다. 아래는 그 커밋의 packages/react-client/src/ReactFlightClient.js 변경분 가운데, 직렬화된 서버 함수 참조를 실제 모듈로 불러오는 함수 loadServerReference() 앞부분에 추가된 검증입니다.

   key: string,
 ): (...A) => Promise<T> {
+  if (key === 'then') {
+    // This should never happen because we always serialize objects with then-functions
+    // as "thenable" which reduces to a chunk with no other fields.
+    return null as any;
+  }
+  const id = metaData.id;
+  if (typeof id !== 'string') {
+    return null as any;
+  }

추가된 분기는 두 가지를 차단합니다. 전달된 속성 키가 then이면 처리를 중단합니다. then은 자바스크립트 런타임이 Promise처럼 취급해 자동으로 호출하는 특수 속성입니다. 또한 서버 함수 식별자가 문자열이 아니면 모듈 해석 경로로 넘기지 않고 반환합니다. 코드 주석은 정상 직렬화에서는 이 상황이 발생하지 않아야 한다고 적고 있습니다. 이 검증이 실제 RCE 경로와 어떻게 연결되는지는 공개되지 않았습니다.

React는 같은 파일에서 역직렬화 중 모델 값을 만드는 createModel()에도 비슷한 검증을 추가했습니다.

-function createModel(response: Response, model: any): any {
+function createModel(
+  response: Response,
+  model: any,
+  parentObject: Object,
+  key: string,
+): any {
+  if (key === 'then' && typeof model === 'function') {
+    // This should never happen because we always serialize objects with then-functions
+    // as "thenable" which reduces to a chunk with no other fields.
+    return null;
+  }
   return model;
 }

같은 커밋에는 변경이 두 가지 더 포함돼 있습니다. 응답 객체를 청크에 그대로 담지 않고 내부 심벌(RESPONSE_SYMBOL)로 감싸는 변경, 그리고 스트리밍 청크와 단발 청크를 구분하도록 전송 필드의 이름 공간을 분리하는 변경입니다. 다만 두 권고가 공격 경로를 공개하지 않아, 어느 변경이 실제 RCE 경로를 차단하는지는 단정할 수 없습니다.

‍

■ 탐지 및 점검

‍

• 운영 중인 애플리케이션의 Next.js 버전이 16.0.0부터 16.4.0 사이인지 잠금 파일(lockfile)과 npm ls next로 확인합니다.

• next.config.ts 또는 next.config.js에서 cacheComponents 옵션이 켜져 있는지 확인합니다.

• 저장소에서 'use cache' 지시어가 선언된 파일과 함수를 찾아, 반환값에 Uint8Array 같은 타입배열이나 ArrayBuffer가 둘 이상 포함되는지 검토합니다.

• Next.js가 아닌 환경에서 React 서버 컴포넌트를 사용한다면 react-server-dom-webpack, react-server-dom-parcel, react-server-dom-turbopack의 설치 버전이 19.0.0~19.0.8, 19.1.0~19.1.9, 19.2.0~19.2.8, 19.3.0 범위에 있는지 확인합니다. 예를 들어 react-server-dom-webpack@19.2.8은 영향 버전이고 react-server-dom-webpack@19.2.9는 패치 버전입니다.

• 캐시 함수가 외부 입력값을 가공 없이 반환값에 포함하는 경로가 있는지 코드 리뷰로 점검합니다.

📌 NOTE

공개된 침해 지표(IoC)는 없습니다.
버전·설정·코드 패턴 점검은 노출 여부를 가리는 기준이며, 침해 여부는 별도 근거로 판단해야 합니다.

‍

■ 대응 방안

‍

• Next.js 16 계열은 16.4.1 이상으로 업그레이드합니다. 권고에 임시 대응책이 없으므로 다른 완화 조치로 대체할 수 없습니다.

• use cache 함수가 없는 애플리케이션도 Vercel 권고에 따라 같은 버전으로 올립니다.

• Next.js를 쓰지 않는 React 서버 컴포넌트 환경은 사용 중인 라인에 맞춰 19.0.9, 19.1.10, 19.2.9, 19.3.1 중 하나로 올립니다.

• 업그레이드 후 잠금 파일에서 react-server-dom-* 패키지가 실제로 패치 버전으로 해석됐는지 확인합니다.

• 같은 날 공개된 이미지 최적화 RCE(CVE-2026-96889)와 Server Actions DoS 권고도 함께 반영해, 15 계열 애플리케이션은 15.5.28로 올립니다.

‍

[참고 자료]

• Next.js 보안 업데이트 공지(2026-10-14)

• Next.js 보안 권고 — use cache 함수의 미인증 원격 코드 실행

• React 보안 권고 — React Server Components 미인증 원격 코드 실행

• React 패치 커밋 — Flight 전송 프로토콜 개선(19.3.1)

• Next.js v16.4.1 릴리스 노트

• React 릴리스 목록

• Next.js 공식 문서 — use cache 지시어

• SecurityOnline — Next.js 긴급 보안 업데이트 보도

• Netlify 변경 로그 — Next.js·React 보안 릴리스 안내

  • #EQST_NOW
  • #취약점

관련 서비스

더 많은 보안 인사이트

SK쉴더스 유튜브 채널에서 확인하세요.

SK쉴더스 유튜브 채널에서 확인하세요.
보안 트렌드와 대응방법

매월 뉴스레터로 확인하세요.

매월 뉴스레터로 확인하세요.