
Next.js 보안 업데이트 정리 — 16.3.8·15.5.27에서 패치된 취약점 7건
Next.js가 2026년 9월 보안 업데이트로 취약점 7건을 패치했다. 이미지 최적화 SSRF(High), 자체 호스팅 SSG/ISR 캐시 포이즈닝, 'use cache'의 Draft Mode 유출까지 — v16.3.8·v15.5.27에서 무엇이 막혔고 어떤 설정이 영향을 받는지 정리했다.
의존성 보안 알림은 보통 피로감부터 옵니다. 분기마다 뜨고, 대부분은 "우리 설정엔 해당 없음"으로 끝나니까요.
그런데 이번 Next.js 9월 패치는 한 번 훑고 넘기기가 좀 어렵습니다. 7건 중 5건이 특정 설정을 켠 앱만 골라서 때리는데, 그 설정들이 하필 요즘 많이 쓰는 것들이거든요.

버전부터. v16.3.8(Active LTS), v15.5.27(Maintenance LTS) 두 갈래로 나왔습니다.
bash
npm install next@16.3.8 # 16.3 라인
npm install next@15.5.27 # 15.5 라인
그리고 먼저 짚어야 할 게 하나 있습니다. Vercel은 지난주 예고 공지에서 Critical 1건과 High 1건을 이번 릴리스에 싣겠다고 했다가, 업스트림 의존성 지연으로 두 건을 미뤘습니다. 이번 패치는 완결이 아니라는 뜻입니다. 올리고 나서 "보안 업데이트 완료"로 체크해 두면, 다음 릴리스가 떴을 때 또 급하게 움직여야 합니다.
7건을 한 장으로
| 취약점 | 심각도 | 영향받는 조건 |
|---|---|---|
| 이미지 최적화 SSRF (CVE-2026-94483) | High | images.remotePatterns 설정 시 |
| SSG/ISR 캐시 포이즈닝 (CVE-2026-94543) | Medium | 자체 호스팅 + Pages Router |
| catch-all 캐시 포이즈닝 (CVE-2026-94484) | Medium | 루트 catch-all + SSG/ISR |
| 메타데이터 이미지 정보노출 (CVE-2026-94485) | Medium | App Router + webpack 빌드 |
중첩 use cache 캐시 키 누락 (GHSA-h694-7cp9-m8p3) | Medium | Cache Components 사용 시 |
| Draft Mode 콘텐츠 유출 (CVE-2026-94544) | Medium | Cache Components + Draft Mode |
| 개발서버 MCP 정보노출 (CVE-2026-94486) | Low | next dev 실행 중에만 |
High 1건, Medium 5건, Low 1건. 표를 세로로 훑으면 공통점이 보입니다. 캐시가 7건 중 4건에 끼어 있습니다.
이미지 최적화 SSRF — 유일한 High
공격자가 조작한 원격 URL이 허용 목록을 통과하면, 이미지 최적화 과정에서 서버가 그 URL로 직접 요청을 날립니다. 사설 IP 대역처럼 바깥에서는 닿을 수 없는 곳까지요.
images.remotePatterns를 아예 설정하지 않은 앱은 해당 없음.
여기에 함정이 있습니다. remotePatterns는 이미지가 안 뜨면 개발 도중에 바로 막히는 설정이라, 와일드카드를 넓게 열어두고 그냥 넘어가는 경우가 흔합니다. 그 "일단 열어둔" 패턴이 정확히 이 취약점의 전제 조건입니다. 패치와 별개로, 지금 열려 있는 호스트 패턴이 실제로 필요한 범위인지는 한 번 봐야 합니다.

자체 호스팅이면 캐시 포이즈닝 2건
두 건 모두 Vercel 배포는 영향 없다고 명시돼 있습니다. 뒤집으면 직접 돌리는 쪽만 맞는 문제라는 얘기입니다.
- CVE-2026-94543 — Pages Router에서 SSG/ISR 페이지의 캐시 항목이 다른 경로의 콘텐츠로 교체됩니다. 한 번 오염되면 재검증 전까지 모든 방문자가 엉뚱한 페이지를 봅니다.
- CVE-2026-94484 — 루트 레벨 catch-all 페이지를 SSG/ISR과 함께 쓰면, 인증 없는 조작 요청 한 번으로 공유 응답 캐시가 오염됩니다. 어드바이저리는 이걸 교차 사용자 콘텐츠 치환에 더해 지속적 서비스 거부로 분류합니다.
캐시 포이즈닝이 까다로운 이유는 조용해서입니다. 500 에러가 나면 알림이 울리지만, 캐시가 바뀌어 200으로 멀쩡하게 잘못된 페이지를 내주면 모니터링에는 아무것도 안 잡힙니다.
webpack으로 빌드했다면 메타데이터 이미지
App Router에서 opengraph-image, twitter-image 같은 메타데이터 이미지 라우트가 dynamicParams 설정을 무시합니다. generateStaticParams()에서 일부러 제외한 동적 세그먼트의 메타데이터 이미지 URL을 공격자가 그대로 요청할 수 있다는 의미입니다. 아직 공개하지 않은 글의 제목이나 썸네일이 OG 이미지 형태로 새어 나가는 그림이죠.
Turbopack으로 빌드한 앱은 해당 없습니다. 번들러 선택이 보안 노출 범위를 가르는 사례가 하나 생긴 셈입니다.
'use cache'를 켰다면 두 건 더
Cache Components(또는 experimental.useCache)를 쓰는 쪽에 두 건이 몰렸습니다.
캐시 키 누락(GHSA-h694-7cp9-m8p3) — use cache 함수가 루트 파라미터를 읽는 또 다른 use cache 함수를 호출할 때, 바깥 함수의 캐시 키에서 그 루트 파라미터가 빠집니다. A 값으로 만들어진 콘텐츠가 B 값 요청에 나갈 수 있다는 뜻입니다. 다만 유출되는 값을 공격자가 고를 수는 없다는 게 어드바이저리의 설명입니다.
Draft Mode 유출(CVE-2026-94544) — 이쪽이 훨씬 불편합니다. 같은 키에 대해 진행 중인 캐시 채우기가 Draft Mode 요청과 일반 요청을 구분하지 않고 공유됩니다. 편집자가 초안을 미리 보는 순간과 일반 요청이 겹치면, 인증 없는 방문자가 미발행 콘텐츠를 그대로 받습니다. 그 요청이 페이지를 프리렌더하기까지 하면 미발행 내용이 생성된 페이지에 굳어버려서, 재검증 전까지 이후 방문자 전원에게 나갑니다.
CMS를 붙여 쓰는 팀에게 이건 단순 버그가 아니라 엠바고 사고입니다.
next dev의 MCP 엔드포인트
심각도는 Low인데 성격이 묘합니다. next dev 개발 서버가 노출하는 MCP 엔드포인트가 요청이 어느 사이트에서 왔는지 검증하지 않습니다. 개발자가 악성 사이트를 방문하기만 해도 그 사이트가 로컬 개발 서버를 긁어갈 수 있습니다. 가져가는 건 디스크상의 프로젝트 경로, 에러 리포트에 담긴 소스 코드 조각, 라우트 목록, 개발 로그입니다.
운영 배포에는 이 엔드포인트가 아예 없습니다. 털리는 대상이 서비스가 아니라 개발자 노트북인 셈입니다.
여기에 한국 상황을 겹쳐 보면 체감 위험도가 달라집니다. 캐시 포이즈닝 두 건에 똑같이 붙은 "Vercel 배포는 영향 없음"이라는 단서는, 국내처럼 자체 호스팅 비중이 높은 환경에서는 사실상 면제가 아니라 가중 조건입니다. 보안 규정이나 망 분리 때문에 사내 쿠버네티스나 국내 클라우드에 직접 올리는 팀이 많고, 그런 팀은 Vercel 사용자가 겪지 않는 문제를 전부 떠안게 됩니다. 어드바이저리의 "영향 없음" 문구를 읽을 때 우리 배포 형태를 먼저 대입해야 하는 이유죠.
실무 순서를 정한다면 저는 설정 점검을 패치보다 앞에 두겠습니다. 버전 올리는 건 어차피 명령 한 줄이지만, images.remotePatterns에 넓게 열어둔 와일드카드나 experimental.useCache 플래그가 왜 켜져 있는지는 아무도 기억 못 하는 경우가 많거든요. 7건 중 5건이 "이 설정을 켰다면"으로 시작한다는 건, 패치를 올려도 공격 표면 자체는 그대로 남는다는 뜻이기도 합니다.
마음에 걸리는 지점도 있습니다. webpack은 취약하고 Turbopack은 아니라는 구분이 생기면서, 번들러 마이그레이션이 성능 선택에서 보안 압박으로 성격이 바뀌었습니다. Cache Components처럼 비교적 새 기능에 Medium 두 건이 몰린 것도 신기능을 일찍 도입한 팀이 치르는 비용에 가깝고요. 그리고 가장 중요한 건, Critical과 High 각 1건이 아직 나오지 않았다는 사실입니다. 지금 올리는 버전은 중간 정산이지 마감이 아닙니다.
지금 할 일
next버전을 16.3.8 또는 15.5.27로 올린다.images.remotePatterns에 불필요하게 넓은 패턴이 있는지 확인한다.- 자체 호스팅이라면 SSG/ISR 캐시를 한 번 재검증한다 — 이미 오염된 항목을 패치가 지워주지는 않는다.
- Cache Components와 Draft Mode를 함께 쓴다면, 최근 생성된 정적 페이지에 미발행 내용이 섞이지 않았는지 본다.
- 다음 릴리스를 기다린다. 미뤄진 두 건이 남아 있다.
여러분 프로젝트는 몇 번 항목에 걸리시나요? 자체 호스팅이라면 캐시 쪽을, Vercel이라면 이미지 최적화와 use cache 쪽을 먼저 보시는 게 빠를 겁니다.
📎 출처: 원문 보기
- nextjs.orghttps://nextjs.org/blog/september-2026-security-release
댓글 0
댓글을 불러오는 중…







