

번역 : React Server Components에서 치명적인 취약점(CVE-2025-55182)이 책임감 있는 방식으로 공개되었습니다. 이 취약점은 React 19 및 이를 사용하는 프레임워크(Next.js 포함, CVE-2025-66478)에 영향을 줍니다.
오늘 아침 Vercel로부터 위와 같은 이메일이 전달받았습니다. LogHub의 웹 프로젝트 Next.js를 사용하고 있었기 때문에, 즉시 Repository의 Security 탭을 확인했습니다. 그 결과, Dependabot이 CVE-2025-66478 취약점에 대한 경고 티켓을 열어둔 상태였고, 심각도가 무려 Critical(10/10) 등급의 취약점이었습니다!

이에 빠르게 대응하기 위해 취약점에 대한 패치가 이루어진 버전으로 react, react-dom 그리고 next 패키지를 업그레이드한 후, 해당 취약점의 상세 내용을 조사하기 시작했습니다.
이 아티클은 Security Advisory: CVE-2025-66478를 참조하여 작성되었습니다.
CVE-2025-66478은 CVSS 점수가 10(만점)으로 치명적인 취약점입니다. 이 취약점은 공격자가 RSC(React Server Components) 프로토콜을 사용하여 RCE(Remote Code Execution: 원격 코드 실행) 공격을 수행할 수 있도록 허용합니다.
또한, CVE-2025-66478은 CVE-2025-55182에서 파생되었으며, 두 취약점의 차이는 다음과 같습니다:
CVE-2025-66478 : next 패키지에 대한 취약점CVE-2025-55182 : RSC(React Server Components) 프로토콜에 대한 취약점입니다.
react-server-dom-webpack: < 19.2.0, react-server-dom-turbopack: < 19.2.0관련 PR : facebook/react/pull/35277
React 프로젝트에서 CVE-2025-55182 취약점이 근본적으로 발생한 원인은 requireModule 함수입니다. 이 함수는 번들러가 제공하는 런타임 require 함수(parcelRequire)를 사용해 모듈 레지스트리에서 특정 모듈을 로드한 뒤, 해당 모듈의 특정 export를 반환하는 헬퍼 함수입니다.
// 취약한 구현
export function requireModule<T>(metadata: ClientReference<T>): T {
const moduleExports = parcelRequire(metadata[ID]);
return moduleExports[metadata[NAME]];
}
기존 구현은 metadata[NAME] 값을 검증하지 않고, 바로 moduleExports[metadata[NAME]]에 접근합니다. 이로 인해, 메타데이터 조작을 통해 의도하지 않은 프로퍼티에 접근할 수 있었습니다. 이를 방지하기 위해 수정한 코드는 다음과 같습니다.
// 수정된 구현
export function requireModule<T>(metadata: ClientReference<T>): T {
const moduleExports = parcelRequire(metadata[ID]);
if (hasOwnProperty.call(moduleExports, metadata[NAME])) {
return moduleExports[metadata[NAME]];
}
return (undefined: any);
}
수정된 구현에서는 hasOwnProperty.call을 사용해 moduleExports가 metadata[NAME] 프로퍼티를 직접 소유하고 있는지 검증합니다. 만약 그렇지 않은 경우에는 undefined를 반환하여 임의 프로퍼티 접근을 방지합니다.
ejpir/CVE-2025-55182-poc 레포지토리를 참조하여 작성되었습니다.
$ git clone [email protected]:ejpir/CVE-2025-55182-poc.git
$ cd CVE-2025-55182-poc
$ npm install
$ npm run start
$ npm run exploit # RCE 공격(vm#runInThisContext 호출을 통한 임의 코드 실행)
위 명령어들을 통해 취약점이 존재하는 서버를 실행하고, 원격 코드 실행 공격을 시도할 수 있습니다. exploit 스크립트로 실행할 수 있는 케이스 외에도 공격 가능한 RCE 가젯은 다음과 같습니다:
| Gadget | Description |
|---|---|
vm#runInThisContext |
현재 컨텍스트에서 임의의 JS 코드 실행 |
vm#runInNewContext |
새로운 컨텍스트(sandbox)에서 임의의 JS 코드 실행 |
child_process#execSync |
셸 명령어 실행 |
child_process#execFileSync |
바이너리 파일 실행 |
child_process#spawnSync |
새로운 프로세스 생성(객체 반환) |
fs#readFileSync |
임의의 파일 읽기 |
fs#writeFileSync |
임의의 파일 쓰기 |
무시무시합니다...
이번 CVE-2025-66478 및 CVE-2025-55182 취약점은 React 생태계에 큰 충격을 주었으며, 특정 라이브러리 및 프레임워크에 의존하는 많은 웹 애플리케이션의 보안에 심각한 위협이 될 수 있음을 보여주었습니다.
Cloudflare WAF proactively protects against React vulnerability
Cloudflare는 이번 취약점에 대응하기 위해 모든 WAF(Web Application Firewall) 사용자에게 해당 취약점을 차단하는 WAF 규칙을 신속하게 배포했습니다. (Cloudflare는 신입니다...)
로그인 후 댓글을 작성할 수 있습니다.