2025년 12월 초, React Server Components(RSC)에서 인증 없이 서버에서 임의 코드 실행(RCE) 이 가능한 치명적인 취약점이 공개됐다. 이 이슈는 React 측에서 CVE-2025-55182, Next.js 측에서 CVE-2025-66478로 공지되었고, 공통적으로 CVSS 10.0(최상위 등급) 을 받았다. (React)
이 글에서는:
- RSC(React Server Components)가 무엇인지
- 이번 RSC 취약점이 어떤 구조적 문제인지
- 공격 코드(Exploit)가 어떤 식으로 동작하는지 개념적으로
- 개발자/운영자가 당장 무엇을 해야 하는지
를 정리한다.
1. RSC(React Server Components)는 무엇인가?
1-1. 기존 CSR/SSR과 뭐가 다른가?
전통적인 React 앱은 크게 두 가지 방식으로 렌더링한다.
- CSR(Client-Side Rendering): 브라우저가 JS 번들을 받아서 UI를 전부 그린다.
- SSR(Server-Side Rendering): 서버에서 HTML을 만든 뒤 브라우저로 보내고, 이후에 JS가 “하이드레이션”을 통해 인터랙션을 붙인다.
React Server Components(RSC) 는 여기서 한 걸음 더 나가서,
“일부 컴포넌트는 아예 서버에서만 돌고, 그 결과만 클라이언트에 스트리밍하자”는 개념이다. (React)
핵심 포인트를 정리하면:
- 서버 전용 컴포넌트(서버 컴포넌트)를 정의할 수 있다.
- 이 컴포넌트는 Node 환경에서 돌아가며, 데이터베이스/파일 시스템 등 백엔드 리소스에 직접 접근한다.
- 브라우저로는 이 컴포넌트의 JS 코드가 아니라, 직렬화된 결과(Flight payload) 만 보내진다.
- 클라이언트는 이 스트림을 받아 기존 React 트리에 합쳐서 UI를 완성한다. (React)
Next.js 13 App Router 이후의 기본 구조가 바로 이 RSC를 중심으로 설계되어 있고, React 19에서 정식으로 Flight 프로토콜과 함께 도입되었다. (Snyk)
1-2. 왜 RSC가 매력적이었나?
RSC가 등장한 이유는 간단하다. 프론트엔드가 너무 “무거워졌기” 때문이다.
- 대형 라이브러리를 전부 브라우저로 보내지 않고, 서버에 남겨둘 수 있다.
- 서버에서 데이터 페칭과 렌더링을 함께 처리해 waterfall 요청을 줄인다.
- 민감한 토큰/키는 브라우저로 절대 내려보내지 않고, 서버 코드 안에 숨길 수 있다. (tech.kakaopay.com)
즉, RSC는 성능 + DX + 보안(원래는…) 을 모두 잡기 위한 야심찬 기능이었다.
문제는, 이걸 위해 도입한 Flight 프로토콜 이 이번 RCE의 공격 표면이 됐다는 점이다.
2. RSC 취약점(CVE-2025-55182 / 66478)은 무엇인가?
2-1. 취약점 요약
React 팀 공식 블로그와 여러 보안 업체 분석을 종합하면, 이번 이슈의 본질은 다음과 같다. (React)
Flight 프로토콜을 통해 들어오는 RSC 페이로드를 역직렬화하는 과정에서,
공격자가 조작한 데이터를 “데이터”가 아니라 “코드 경로”로 해석해 버리는 논리적 역직렬화 취약점.
구체적으로는:
- 취약 코드는
react-server및react-server-dom-*패키지 내부의 Flight 처리 부분에 존재한다. (React) - 클라이언트 → 서버로 전송되는 Server Function 호출 / RSC 업데이트 요청 을 해석할 때,
- “어떤 함수를 호출할지”에 대한 참조(reference)를 신뢰하고,
- 그 참조가 실제로 허용된 함수인지, 안전한 대상인지 충분히 검증하지 않는다.
- 그 결과, 공격자가 특정 형태의 Flight 청크를 만들어 Node.js의 내부 객체, 모듈 로더,
child_process같은 위험한 함수에 간접적으로 도달하게 만들 수 있다. (Checkmarx)
이 취약점은:
- 인증이 필요 없다 (pre-auth RCE)
- React 19 계열과 이를 사용하는 Next.js 15–16 App Router 기본 설정에 영향을 준다.
- 새로 만든 Next.js 앱(
create-next-app)조차, 아무 커스텀 코드 없이도 취약할 수 있는 것으로 보고됐다. (upwind.io)
그래서 보안 업계에서 CVSS 10.0, “React2Shell / React4Shell” 같은 이름으로 부르며 강하게 경고하고 있다. (feature-sliced.design)
2-2. 어떤 앱이 영향을 받는가?
대부분의 분석과 공식 권고를 정리하면: (React)
- 취약 대상
- React 19 +
react-server-dom-*를 사용하는 RSC 지원 환경 - Next.js 15–16에서 App Router + RSC/Server Actions를 사용하는 앱
- React 19 +
- 부분 논쟁 포인트
- Server Function 엔드포인트를 직접 구현하지 않아도, RSC를 지원하는 설정 자체만으로도 취약할 수 있다는 리서치가 있다. (@Ounols)
- 직접적인 영향 X(이번 CVE에 한정)
- RSC를 전혀 사용하지 않는 순수 CSR 앱
- Next.js 옛 Pages Router만 사용하는 레거시 앱
- 서버에서 RSC 관련 패키지를 아예 로드하지 않는 환경
- (캐나다 사이버 보안 센터, Snyk 등 일부 권고문에서 “RSC/서버 함수 비활성화 시 이번 CVE의 공격면은 사라진다”고 명시) (York University)
단, 이건 어디까지나 이번 RSC RCE 취약점에 한정된 얘기다.
SSR, API 라우트, 다른 라이브러리의 취약점은 여전히 별도의 공격면으로 존재한다.
3. 공격 시나리오 & 코드 예시(개념적)
이미 여러 보안 업체와 연구자들이 PoC(Proof of Concept) 익스플로잇 코드를 공개한 상태다. (Cyber Security News)
이 글에서는 실제 악성 코드를 그대로 가져오지 않고, “어떤 식으로 동작하는지”를 이해하기 위한 개념 수준의 예시만 정리한다.
3-1. RSC / Flight 요청 흐름 복습
RSC + Server Functions가 동작할 때의 기본 흐름은 대략 이렇다. (Checkmarx)
- 클라이언트 컴포넌트에서 Server Function 을 호출한다.
- React는 이 호출을 Flight 프로토콜 포맷으로 직렬화해 HTTP 요청으로 전송한다.
- 서버는 HTTP 요청을 받아 Flight 청크를 역직렬화 → 어떤 서버 함수인지 찾아서 호출 한다.
- 서버 함수 결과를 다시 Flight 포맷으로 직렬화해 클라이언트로 스트리밍한다.
문제는 3번 단계, “역직렬화 + 함수 참조 해석” 에 있다.
3-2. 서버 쪽 취약 로직(개념적 코드)
아주 단순화하면, 취약한 로직은 아래처럼 생각할 수 있다 (실제 구현과 동일하지 않다):
// ⚠ 개념 설명용 의사 코드 (실제 React 코드 아님)
function handleFlightRequest(req) {
const chunk = decodeFlight(req.body); // Flight 페이로드 역직렬화
// chunk.fnRef 에는 "어떤 서버 함수를 호출할지"에 대한 정보가 들어 있음
const fn = resolveFunctionReference(chunk.fnRef); // 여기서 사용자 입력을 너무 신뢰함
const args = chunk.args;
// 검증 없이 곧바로 호출
return fn(...args);
}
여기서 fnRef가 정상적인 서버 함수를 가리키는 것이 아니라,
Node.js의 내부 객체나 위험한 함수(예: child_process.exec)로 이어지는 체인을 가리키도록 조작될 수 있다면?
공개된 PoC들은 바로 이 부분을 노려,
- Flight 프로토콜이 허용하는 형식 안에서
- 특정 객체 그래프를 타고
- 최종적으로 OS 명령 실행이 가능한 함수까지 도달하도록
치밀하게 직렬화된 페이로드를 만든다. (GitHub)
3-3. 공격 코드가 하는 일(고수준)
공개 PoC들이 공통적으로 수행하는 단계는 대략 다음과 같이 요약할 수 있다. (GitHub)
- 대상 스캐닝
- 인터넷에 노출된 React/Next.js 서버 중 RSC/Server Functions 엔드포인트가 열려 있는지 스캔
- 특정 경로나 헤더 패턴(Flight 엔드포인트)을 찾는다.
- 특수하게 직렬화된 Flight 페이로드 생성
- 정상적인 Server Function 호출처럼 보이도록 포맷을 맞추되,
fnRef나 인자 부분에 의도적으로 조작한 참조/값 을 넣는다.- 이 참조가 역직렬화 과정에서 위험한 함수 체인으로 해석되도록 구성한다.
- 원격 코드 실행
- 최종적으로 Node.js에서
child_process/vm/ 기타 코드 실행 기능에 도달하여 touch /tmp/pwned같은 간단한 명령부터,- 쉘을 열거나 랜섬웨어/백도어 설치 스크립트를 다운로드하는 명령까지 실행 가능해진다.
- 최종적으로 Node.js에서
- 후속 공격
- 얻은 권한으로 추가 백도어 설치, 데이터 유출, 랜섬웨어 배포 등 일반적인 RCE 시나리오를 수행한다. (데일리시큐)
현재 그레이노이즈 등에서는 이미 자동화된 대량 스캐닝/공격 트래픽이 관측되고 있다고 보고한다. (greynoise.io)
정리하면:
공격 코드는 “React/Next.js를 해킹하는 마법 같은 스크립트”라기보다는,
Flight 프로토콜을 잘 이해하고, 역직렬화 로직이 “코드처럼” 해석하는 틈을 파고드는 특수 페이로드 생성기에 가깝다.
4. 어떻게 대처할 것인가?
4-1. 최우선: React / Next.js 패치
정식 패치 적용이 가장 중요하다.
- React 팀은
react-server-dom-*패키지에 대한 보안 업데이트를 배포했다. (React)- 예:
react-server-dom-webpack19.0 → 19.0.1- 19.1.0–19.1.1 → 19.1.2
- 19.2.0 → 19.2.1 등
- 예:
- AWS, Aikido 등도 “React 19.x + RSC 사용 시 위 버전 이상으로 즉시 업그레이드하라”고 안내한다. (Amazon Web Services, Inc.)
- Next.js 측에서도 App Router 기반 프로젝트는 패치된 15/16 버전으로 업데이트할 것을 권고한다. (Next.js)
한국 KRCERT 역시 같은 내용의 업데이트 권고를 게시했다. (KISA 보호나라)
실무 팁:
- 패치 후에는 CI/CD 파이프라인에서 잠재적으로 남아 있을 수 있는 구버전 lock 파일(예:
yarn.lock,package-lock.json)도 같이 점검하는 게 좋다.- 모노레포/멀티 패키지 구조라면, 각 패키지별
react-server-dom-*버전이 다르지 않은지 확인.
4-2. 임시 대응: RSC / Server Functions 비활성화
즉시 패치가 불가능한 환경이라면, 여러 기관에서 아래와 같은 임시 조치를 제안한다. (York University)
- RSC 및 서버 함수 기능 비활성화
- React 19: 서버에서 RSC/Server Functions를 사용하는 경로/엔드포인트를 임시로 막는다.
- Next.js:
- App Router에서 RSC/Server Actions를 사용하는 페이지를 비활성화하거나
- 문제가 되는 라우트를 프록시 뒤로 숨기거나
- 가능하다면 Pages Router로 임시 롤백
- 공개 엔드포인트 축소
- 외부 인터넷에서 직접 접근 가능한 RSC/Server Function 엔드포인트를 최소화
- 사내망 또는 VPN 뒤로 숨기기
이렇게 하면 이번 CVE와 직결되는 공격면은 제거할 수 있다.
물론 애플리케이션 기능에 영향을 줄 수 있으니, 비즈니스 영향도와 균형을 맞추어야 한다.
5. RSC를 사용하는 개발자가 얻어야 할 교훈
이번 이슈가 주는 메시지는 꽤 명확하다.
- “데이터 직렬화”와 “코드 실행 경로”가 뒤섞이지 않도록 설계해야 한다.
- Flight처럼 복잡한 프로토콜에서는 특히, 사용자가 조작 가능한 값이 코드 경로까지 흘러들어가지 않도록 엄격히 검증해야 한다.
- 보안을 “기능별”이 아니라 “요청 경로 / 데이터 흐름별”로 모델링해야 한다.
- App Router, Middleware, API Routes, RSC, Server Functions 등 여러 레이어를 얇게 쌓다 보면,
- “위 레이어에서 인증했겠지”라고 믿다가 아래 레이어에서 우회가 터질 수 있다.
- 새로운 추상화는 곧 새로운 공격면이다.
- RSC는 확실히 DX/성능 측면에서 매력적인 기능이지만,
- 그만큼 복잡한 직렬화 프로토콜과 서버 실행 경로를 내포한다.
- 이런 기능을 도입할 때는 성능 벤치마크만 볼 게 아니라, 공격 모델 도 함께 설계해야 한다.
마무리
정리하면:
- RSC는 “서버 전용 컴포넌트 + Flight 프로토콜”을 통해 클라이언트와 서버 사이의 렌더링을 세밀하게 쪼개는 기능이다.
- 이번 CVE-2025-55182 / 66478는 그 Flight 역직렬화 과정에서,
- 사용자 입력을 위험한 함수 참조로 해석해 버리는 논리적 역직렬화 취약점이며,
- 인증 없는 RCE(CVSS 10.0)로 이어진다.
- 공개 PoC들은 이 취약점을 이용해 공격자가 조작한 Flight 페이로드를 보내,
- Node 내부 객체 체인을 타고
- OS 명령 실행까지 도달하는 과정을 자동화하고 있다.
- 대응은
- React/Next.js 패치가 최우선,
- 패치 전에는 RSC/Server Functions 비활성화 + WAF·권한 최소화·모니터링 강화가 현실적인 방안이다.
'Web > React' 카테고리의 다른 글
| [React] useMemo, useEffect 에러 (인 줄 알았던 휴먼에러) (0) | 2025.03.23 |
|---|---|
| [React] useRef, useMemo, useCallback (1) | 2024.12.13 |
| React 번들링 (1) | 2024.12.01 |
| React의 특징 (2) | 2024.11.17 |