CVE-2025-55182 · React2Shell: React Server Components에서 프로토타입 오염을 통한 RCE
I’m happy to translate the article for you, but I’ll need the full text of the post (excluding the source link you’ve already provided). Could you please paste the content you’d like translated? Once I have it, I’ll keep the source link unchanged and translate the rest into Korean while preserving all formatting, markdown, and technical terms.
TL;DR
React의 Flight 디시리얼라이저는 .then 메서드를 가진 모든 객체를 Promise로 취급합니다. 조작된 multipart POST를 통해 Object.prototype.then을 오염시키면, 공격자는 Function 생성자를 이용해 임의의 JavaScript를 서버에서 실행시킬 수 있습니다. 결과는 X-Action-Redirect HTTP 헤더를 통해 유출됩니다. 인증이 필요 없으며, 결과는 결정적입니다. CVSS v3.1: 10.0 (Critical).
Background
React Server Components (RSC)는 React 19와 Server Actions와 함께 안정화되었습니다. UI 컴포넌트는 서버에서 실행되고 Flight 직렬화 프로토콜을 통해 클라이언트와 통신합니다. 클라이언트가 Server Action을 호출하면 직렬화된 페이로드를 포함한 multipart POST를 전송합니다. 서버는 페이로드를 역직렬화하고, 액션을 실행한 뒤 결과를 스트리밍으로 반환합니다.
Flight 프로토콜은 JSON이 아니며 타입이 지정된 청크를 갖는 스트리밍 형식입니다. 이 프로토콜의 핵심 메커니즘은 .then 함수가 존재하는 역직렬화된 객체를 모두 Promise로 간주합니다. 이 가정이 취약점의 근본 원인입니다.
Affected: React Server Components를 사용하는 App Router 기반 Next.js 애플리케이션(Next.js 14부터 기본). 명시적으로 정의된 Server Actions가 없어도 취약한 RSC 패키지가 포함되어 있으면 충분합니다.
Vulnerable Code (React 19.0.0 – 19.2.0)
// VULNERABLE
if (obj && typeof obj.then === 'function') {
// behavioral check — bypassable via prototype chain
}
공격자가 Object.prototype에 then 함수를 추가하면 모든 일반 객체가 이를 상속받게 됩니다. 역직렬화 과정에서 실제 Promise와 오염된 객체를 구분할 수 없게 되어 다음과 같은 코드를 실행하게 됩니다:
new Function(_prefix) // attacker‑controlled code
악용 단계
정찰
React 19.0.0–19.2.0 버전을 사용하고 App Router가 적용된 Next.js 앱을 식별합니다. multipart/form-data를 처리하고 Next-Action 헤더를 기대하는 모든 엔드포인트가 유효한 대상이 됩니다. 앱 라우트에 대한 사전 지식은 필요하지 않습니다.
페이로드 구성
다음과 같은 multipart 본문을 생성합니다:
__proto__:then을 설정하여Object.prototype을 오염시킵니다._formData.get을$1:constructor:constructor로 리다이렉트합니다.- 실행할 JavaScript 코드를
_prefix에 제공합니다.
요청 전달
헤더 Next-Action: x와 함께 루트 경로로 단일 POST 요청을 보냅니다. 요청은 정상적인 multipart 페이로드처럼 보이므로 대부분의 WAF가 검사를 통과시킵니다.
서버 측 평가
역직렬화 과정에서 Flight 런타임은 오염된 프로토타입에서 온 .then 메서드를 가진 객체를 만나 new Function(_prefix)를 호출하여 공격자의 코드를 실행합니다.
데이터 탈취
execSync()의 출력이 NEXT_REDIRECT 오류 다이제스트에 삽입됩니다. Next.js는 이를 307 응답으로 변환하고 다음 헤더를 포함합니다:
X-Action-Redirect: /login?a=
a 파라미터를 디코딩하면 명령 실행 결과를 얻을 수 있습니다.
기본 RCE 예시
whoami, id, uname -a와 같은 명령을 취약한 Node.js 서버에서 단일 POST 요청으로 실행할 수 있습니다.
전체 익스플로잇 리소스
완전한 페이로드 구조, 최소 curl 원‑라이너, 그리고 익스플로잇 프레임워크 react2shell.py(지속적인 인터랙티브 쉘, 환경 변수 탈취, 디페이스먼트, 선택적 서비스 거부 모듈 포함)는 **blog.deviannt.com**에 문서화되어 있습니다.
Patch Details
Code Change
// VULNERABLE
- resolvedValue = resolvedValue[key];
// PATCHED
+ if (!resolvedValue.hasOwnProperty(key)) break;
+ resolvedValue = resolvedValue[key];
hasOwnProperty 가드가 프로토타입 체인 탐색을 차단하여, 공격자가 $1:constructor:constructor를 통해 Function 생성자에 도달하는 것을 방지합니다.
Verify Your Installation
node -e "const r = require('react'); const [maj,min,pat] = r.version.split('.').map(Number); \
console.log('React:', r.version, (maj===19 && (min<2||(min===2&&pat<1))) ? '❌ VULNERABLE' : '✓ Patched')"
Post‑Patch Advisory
초기 패치 버전(19.0.1, 19.1.2, 19.2.1)에도 두 개의 후속 CVE가 포함되어 있습니다:
- CVE‑2025‑55184 – DoS (CVSS 7.5)
- CVE‑2025‑55183 – Source Code Exposure (CVSS 5.3)
전체 수정 사항을 적용하려면 19.0.2, 19.1.3, 또는 19.2.2 로 업데이트하십시오.
결론
이 취약점은 정체성 검증이 아닌 행동 검증(typeof obj.then === 'function')에 의존함으로써 발생합니다. “thenable”을 지원하기 위한 이러한 유연성은 프로토타입 오염이 가능할 때 마스터 키가 됩니다. 유사한 문제를 방지하려면 적절한 프로토타입 체인 보호와 보다 엄격한 타입 검증이 필수적입니다.
Full analysis → blog.deviannt.com · CVE‑2025‑55182 · React2Shell
— devianntsec, security research & beyond