게시일: · 수정일:

CVE-2025-55182: React 취약점 절망편

CVE-2025-55182: React 취약점 절망편 들어가며 번역 : React Server Components에서 치명적인 취약점(CVE-2025-55182)이 책임감 있는 방식으로 공개되었습니다. 이 취약점은 React 19 및 이를 사용하는 프레임워크(Next.js 포함,...

작성자: gymynnym

CVE-2025-55182: React 취약점 절망편

들어가며

Email from vercel security
Vercel Security로 부터 도착한 이메일

번역 : 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) 등급의 취약점이었습니다!

GitHub Security Alert for CVE-2025-66478
심각하다!

이에 빠르게 대응하기 위해 취약점에 대한 패치가 이루어진 버전으로 react, react-dom 그리고 next 패키지를 업그레이드한 후, 해당 취약점의 상세 내용을 조사하기 시작했습니다.

취약점 조사

이 아티클은 Security Advisory: CVE-2025-66478를 참조하여 작성되었습니다.

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

CVE-2025-55182

취약점 분석

관련 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 git@github.com: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의 대응

Cloudflare WAF proactively protects against React vulnerability

Cloudflare는 이번 취약점에 대응하기 위해 모든 WAF(Web Application Firewall) 사용자에게 해당 취약점을 차단하는 WAF 규칙을 신속하게 배포했습니다. (Cloudflare는 신입니다…)