Skip to content

security: next 16.3.4 — 이미지 최적화 RCE 패치와 낡은 audit 무시 항목 정리 - #41

Merged
mikim merged 1 commit into
mainfrom
claude/next-16.3.4-security
Sep 9, 2026
Merged

mikim merged 1 commit into
mainfrom
claude/next-16.3.4-security

Conversation

@mikim

@mikim mikim commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

어제(2026-09-08) 공개된 next 16.x critical 권고 두 건이 운영 중인 16.2.12 에 해당한다.

권고 등급 영향 범위 패치
GHSA-2xp9-vwfh-vxw4 — 이미지 최적화 AVIF RCE critical >=16.0.0 <16.3.3 16.3.3
GHSA-p293-qw3h-jr36 — Windows 호스트 RCE critical >=16.0.0 <16.3.3 16.3.3
GHSA-rgj7-g3m4-5g8c — libheif high sharp <0.35.4 0.35.4

실제 노출

Windows 건은 운영 호스트가 리눅스라 해당 없다. AVIF 건은 /_next/image 가 실제로
열려 있지만(로컬 경로 요청에 200) images.remotePatterns 가 없어 외부 URL 은 400 이고
업로드 경로도 없어, 공격자가 만든 AVIF 가 옵티마이저에 닿을 방법이 지금은 없다.
즉 당장 악용 가능한 상태는 아니다. 그래도 같은 오리진에 바이트를 얹을 수단이 하나
생기는 순간 RCE 라, 노출 경로를 계속 논증하는 대신 패치한다.

패치를 미룰 수 없는 이유

pnpm audit --audit-level=high 가 지금 exit 1 이고, 그게 CI 의 마지막 단계다.
checks 는 main 의 필수 상태 검사이므로 머지 버튼이 막히고, deploy.sh 는 CI
failure 인 커밋을 배포하지 않는다. 이 PR 없이는 다음 변경분이 프로덕션에 닿지 못한다.
9/2 이후 CI 가 돌지 않아 아직 red 로 드러나지만 않았을 뿐이다.

곁들여 정리한 것

  • allowBuilds 의 sharp 항목 삭제. 0.35.4 는 install/postinstall 을 선언하지 않아
    (@img 바이너리는 평범한 optional dep) 승인할 빌드가 없다. 남겨두면 아무도 읽지
    않는 핀이 된다.
  • ignoreGhsas 에서 이번 업그레이드로 더는 매칭되지 않는 두 건 삭제 — postcss XSS
    (GHSA-qx2v-qp2m-jg93, 8.5.x 에서 수정)와 sharp/libvips(GHSA-f88m-g3jw-g9cj).
    남은 다섯 건은 여전히 매칭되며 판단 근거도 그대로다.
  • README 의 TRUSTED_PROXY_HOPS 설명 수정. "앞단 프록시 개수를 넣으라"고 쓰여 있었는데
    clientIp()X-Forwarded-For 를 오른쪽에서부터 세고, 오른쪽 끝은 우리 인프라가
    붙인 값이다. 운영 nginx 는 $proxy_add_x_forwarded_for 로 실제 피어를 덧붙이므로
    정답은 0 이고 박스도 0(미설정)으로 돌고 있다. 문서대로 1 로 올리면 nginx 가
    붙이기 이전 항목, 즉 호출자가 보낸 값을 읽게 되어 요청마다 새 rate-limit 버킷을
    만들 수 있다.

검증

CI 와 동일한 5개 게이트를 로컬에서 통과시켰다. 빌드 라우트 수는 46개로 업그레이드 전과 같다.

게이트 결과
tsc --noEmit exit 0
pnpm test 28/28 pass
pnpm build exit 0, 46 routes
check-health.ts exit 0, 12 subsystems
pnpm audit --audit-level=high exit 0 (업그레이드 전 exit 1)

머지하면 배포 폴러가 5분 내에 집어간다. 다만 KST 6·7·8·13 시는 DEPLOY_QUIET_HOURS_KST
배포가 미뤄지는 창이다.

🤖 Generated with Claude Code

2026-09-08 에 next 16.x 를 향한 critical 권고 두 건이 공개됐고, 운영 중인
16.2.12 가 그 범위에 들어간다.

- GHSA-2xp9-vwfh-vxw4 (critical, >=16.0.0 <16.3.3): 이미지 최적화 API 의
  AVIF 처리에서 인증 없는 RCE. 이 사이트에서 /_next/image 는 실제로 열려
  있지만(로컬 경로 요청에 200), images.remotePatterns 를 두지 않아 외부 URL 은
  400 이고 업로드 경로가 없다 — 공격자가 만든 AVIF 가 옵티마이저에 닿을
  방법이 지금은 없다. 그래도 같은 오리진에 바이트를 얹을 방법이 하나라도
  생기면 그때는 RCE 라, 노출 경로를 논증하는 대신 패치한다.
- GHSA-p293-qw3h-jr36 (critical): Windows 호스트 한정. 운영 호스트는 리눅스라
  해당 없지만 같은 패치 버전에서 함께 닫힌다.
- sharp 0.34.5 → 0.35.4 로 따라 올라가며 GHSA-rgj7-g3m4-5g8c (high, libheif)
  도 해소된다.

패치를 미루면 배포 경로 자체가 멈춘다. `pnpm audit --audit-level=high` 가
exit 1 이 되고, 그게 CI 의 마지막 단계다. `checks` 는 main 의 필수 상태
검사이므로 머지 버튼이 막히고, deploy.sh 는 CI failure 인 커밋을 배포하지
않는다. 즉 이 커밋 없이는 다음 변경분이 프로덕션에 닿지 못한다.

곁들여 정리한 것:

- allowBuilds 의 sharp 항목 삭제. 0.35.4 는 install/postinstall 을 아예
  선언하지 않아(@img 바이너리는 평범한 optional dep) 승인할 빌드가 없다.
  남겨두면 아무도 읽지 않는 핀이 된다.
- ignoreGhsas 에서 이번 업그레이드로 더는 매칭되지 않는 두 건 삭제 —
  postcss XSS(GHSA-qx2v-qp2m-jg93, 8.5.x 에서 수정)와 sharp/libvips
  (GHSA-f88m-g3jw-g9cj). 목록을 업그레이드마다 다시 읽지 않으면 낡은 무시가
  쌓이는데, 그건 설명 없는 무시와 똑같은 맹점이다. 남은 다섯 건은 여전히
  매칭되며 판단 근거도 그대로다.

README 의 TRUSTED_PROXY_HOPS 설명도 바로잡았다. "앞단 프록시 개수를 넣으라"
고 쓰여 있었는데, clientIp() 는 X-Forwarded-For 를 오른쪽에서부터 세고 오른쪽
끝은 우리 인프라가 붙인 값이다. 운영 nginx 는 $proxy_add_x_forwarded_for 로
실제 피어를 덧붙이므로 정답은 0 이고 박스도 0(미설정)으로 돌고 있다. 문서를
따라 1 로 올리면 nginx 가 붙이기 이전 항목, 즉 호출자가 보낸 값을 읽게 되어
요청마다 새 rate-limit 버킷을 만들 수 있다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@mikim
mikim merged commit 33f8cdf into main Sep 9, 2026
1 check passed
@mikim
mikim deleted the claude/next-16.3.4-security branch September 9, 2026 04:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant