NextJS는 끝났습니다... 무려 13개의 새로운 보안 취약점 발견
원제 · Yeah it’s over for NextJS... 13 NEW vulnerabilities
핵심 요약
Next.js와 React의 서버 컴포넌트 및 프록시 로직에서 발견된 13개의 취약점은 서버 가용성 마비와 내부망 침투를 허용하므로 즉각적인 최신 버전 업데이트와 서버 측 추가 인증 로직 구현이 필수적입니다.
하이라이트
React와 Next.js 생태계 전반에서 서비스 거부(DoS), 미들웨어 우회, SSRF 등 총 13개의 새로운 보안 취약점(CVE)이 발견되었습니다.
i18n 기능을 활성화한 Pages Router 환경에서 특정 경로 조합을 통해 인증 없이 서버 사이드 props 데이터를 추출하는 7.5점 심각도의 취약점이 확인되었습니다.
서버 컴포넌트의 직렬화 프로토콜인 React Flight의 결함으로 인해 특수하게 제작된 페이로드를 전송할 경우 서버 연산량이 2억 번까지 급증하며 메인 스레드가 차단됩니다.
자체 호스팅 환경의 Next.js 서버에서 'upgrade websocket' 헤더를 악용하면 내부 네트워크의 Redis나 데이터베이스에 접근할 수 있는 8.6점 심각도의 SSRF 공격이 가능합니다.
서버 컴포넌트 데이터(.rsc) 요청 시 쿼리 스트링 검증 미흡으로 인해 일반 사용자에게 HTML 대신 직렬화된 데이터를 노출시키는 캐시 포이즈닝 공격이 발생합니다.
beforeInteractive 스크립트 전략 사용 시 외부 데이터를 이스케이프 없이 처리하여 사용자 브라우저에서 악성 자바스크립트를 실행하는 XSS 취약점이 발견되었습니다.
타임라인
Pages Router의 미들웨어 및 프록시 우회
다국어 설정을 사용하면 동일 페이지에 대해 로케일별 변형 URL이 생성됩니다. Next.js의 경로 매칭 결함으로 인해 기본 케이스(base case)가 보호 범위에서 누락되면서 해커는 NEXT_DATA 스크립트에서 추출한 빌드 ID와 .json 확장자를 결합해 민감한 이메일이나 플래그 데이터를 탈취합니다. 이는 단순히 미들웨어 매처 설정의 문제를 넘어 프레임워크 수준의 경로 해석 오류에서 기인합니다.
- i18n 기능이 활성화된 Pages Router 환경은 특정 데이터 요청 경로를 제대로 보호하지 못합니다.
- 빌드 ID를 포함한 특정 URL 형식을 사용하면 미들웨어의 인증 절차를 건너뛰고 서버 데이터를 직접 조회할 수 있습니다.
- 미들웨어에만 의존하는 보안 구조는 구조적인 우회 가능성을 내포하므로 서버 로직 내 개별 인증이 동반되어야 합니다.
서버 컴포넌트 직렬화 프로토콜을 이용한 서비스 거부(DoS) 공격
기존 방식은 포인터 참조를 찾을 때마다 전체 키 리스트를 처음부터 반복해서 훑는 구조였습니다. 공격자가 20만 개의 무의미한 키와 수천 개의 포인터를 섞어 보내면 서버는 약 2억 번의 문자열 비교를 수행하며 메인 스레드를 점유합니다. 최신 보안 패치는 커서 기반 시스템을 도입하여 한 번 확인한 지점 이후부터 탐색을 이어가도록 수정함으로써 불필요한 반복 연산을 제거합니다.
- React Flight 프로토콜의 역직렬화 방식은 키 탐색 횟수가 기하급수적으로 늘어나는 알고리즘 취약점을 가집니다.
- 악성 페이로드를 전송하면 0.02초 걸리던 응답 시간이 6초 이상으로 늘어나며 서버 가용성이 저하됩니다.
- 탐색 알고리즘을 참조 개수와 키 개수의 곱 연산에서 단순 합 연산으로 개선하여 연산 횟수를 1,000배 이상 단축했습니다.
자체 호스팅 환경에서의 SSRF 취약점과 방화벽 무력화
공격자가 upgrade websocket 헤더와 함께 내부 서버 주소를 전송하면 Next.js는 이를 정당한 앱 경로로 오인하여 요청을 전달합니다. 이 과정에서 방화벽 내부에 위치하여 외부 접근이 차단된 Redis나 DB 관리 페이지의 HTML이 공격자에게 그대로 전달되는 현상이 발생합니다. 패치 이후에는 요청이 설정된 리라이트나 미들웨어 규칙을 따르는지 사전에 검증하는 절차가 강화되었습니다.
- Vercel 이외의 환경에서 구동되는 Next.js 서버는 요청 헤더 조작을 통한 내부망 침투에 취약합니다.
- request-target 헤더에 내부 IP를 주입하면 Next.js 서버가 대리인 역할을 수행하여 비공개 데이터를 반환합니다.
- 경로 해석 함수에 상태 코드와 요청 완료 여부를 확인하는 가드 로직을 추가하여 부정한 프록시 요청을 차단합니다.
캐시 포이즈닝 및 스크립트 이스케이프 미흡을 이용한 XSS
캐시 포이즈닝은 단순히 확장자 끝부분만 확인하는 허점을 이용해 일반 사용자가 깨진 직렬화 데이터를 받게 만듭니다. XSS의 경우 dangerouslySetInnerHTML 내부에서 동작하는 속성값들이 문제인데, 공격자가 쿼리 파라미터에 닫는 스크립트 태그를 포함시키면 기존 보안 스크립트가 강제 종료되고 그 자리에 피싱 폼이나 쿠키 탈취 코드가 실행됩니다. 이는 복잡해진 프레임워크 기능들이 기본적인 보안 수칙인 이스케이프 처리와 충돌하며 발생한 사례들입니다.
- URL 확장자 검사 시 쿼리 스트링을 무시하지 못해 서버 컴포넌트 데이터가 HTML 캐시에 저장되는 오류가 수정되었습니다.
- beforeInteractive 전략을 사용하는 스크립트 태그는 외부 파라미터 유입 시 태그 탈취 공격에 노출됩니다.
- JSON.stringify가 HTML 닫는 괄호를 적절히 처리하지 못하는 점을 악용하여 임의의 자바스크립트를 삽입할 수 있습니다.
설명
Next.js가 13개의 CVE(보안 취약점)를 수정하는 보안 업데이트를 발표했습니다. 이 중 6개는 '높음' 등급의 심각도를 가지고 있습니다. 이번 영상에서는 미들웨어 우회, React Flight 프로토콜을 이용한 서비스 거부(DoS), 서버 측 요청 위조(SSRF), 그리고 사이트 간 스크립팅(XSS) 문제에 대해 자세히 분석해 봅니다. 서버 컴포넌트 도입은 과연 실수였을까요? 🔗 관련 링크 보안 블로그: [https://vercel.com/changelog/next-js-may-2026-security-release](https://vercel.com/changelog/next-js-may-2026-security-release) ❤️ 채널 소개 완전히 새로운 차원의 관측성 스택: [https://betterstack.com/](https://betterstack.com/) 텍스트 튜토리얼: [https://betterstack.com/community/](https://betterstack.com/community/) 예제 프로젝트: [https://github.com/BetterStackHQ](https://github.com/BetterStackHQ) 📱 소셜 미디어 Twitter: [https://twitter.com/betterstackhq](https://twitter.com/betterstackhq) Instagram: [https://www.instagram.com/betterstackhq/](https://www.instagram.com/betterstackhq/) TikTok: [https://www.tiktok.com/@betterstack](https://www.tiktok.com/@betterstack) LinkedIn: [https://www.linkedin.com/company/betterstack](https://www.linkedin.com/company/betterstack) 📌 챕터: 00:00 인트로 00:41 미들웨어 우회 03:50 서비스 거부 (DoS) 07:50 요청 위조 (최고 심각도) 10:57 캐시 포이즈닝 12:45 사이트 간 스크립팅 (XSS) 15:09 실수였나
