
CVE-2026-40864에 대한 개념 증명: Sec-Fetch-Mode: no-cors를 악용한 교차 출처 폼 POST를 통한 JupyterHub XSRF 우회. PoC HTML, 근본 원인 분석, 공개 타임라인을 포함합니다.
Sec-Fetch-Mode: no-cors)를 통한 JupyterHub XSRF 우회심각도: 중간 (CVSS 5.4)
CWE: CWE-352 — 교차 사이트 요청 위조 (XSRF)
영향 범위: jupyterhub 4.1.0 ≤ 버전 < 5.4.5 (5.4.5에서 패치됨)
보안 공지: GHSA-m68r-v472-jgq9
NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-40864
공로: Romain Deperne
JupyterHub의 XSRF 보호 기능(4.1.0에서 재작성됨)은 요청이 동일 출처인지 판단하기 위해 Sec-Fetch-Mode 요청 헤더를 사용했습니다. 이 기능은 Sec-Fetch-Mode: no-cors를 동일 출처로 간주했지만, no-cors는 브라우저가 교차 출처 "단순" 폼 제출 시 전송하는 값과 정확히 일치합니다. 그 결과, Hub의 폼 엔드포인트(/hub/spawn, /hub/accept-share)로 향하는 교차 출처 HTML 폼 POST가 XSRF 검사를 완전히 우회했습니다.
JSON API는 영향을 받지 않습니다(단순하지 않은 콘텐츠 타입을 요구하므로 CORS 프리플라이트가 강제됨). 이 방식으로 도달 가능한 것은 HTML 폼 엔드포인트뿐입니다.
XSRF 로직은 동일 출처 탐색을 포착하기 위한 일련의 Sec-Fetch-* 상태에 대해 "신뢰됨"으로 단락 처리합니다. Sec-Fetch-Mode: no-cors가 그 신뢰 집합에 포함되어 있었습니다. 그러나 no-cors는 브라우저가 다른 출처로 전송하는 단순 <form method=POST>에 부여하는 모드로, 바로 토큰이 막아야 하는 전형적인 CSRF 벡터입니다. 따라서 단순 폼 본문을 허용하고 이 XSRF 게이트에만 의존하는 상태 변경 엔드포인트는 교차 출처에서 위조 가능합니다.
이를 실제 엔드포인트에 대입하면: /hub/spawn(피해자의 서버 시작)과 /hub/accept-share(피해자가 공격자의 서버 공유를 수락하도록 함)는 모두 이 게이트 뒤에 있는 폼 POST입니다.
/hub/spawn — 공격자 페이지가 피해자의 단일 사용자 서버를 동의 없이 시작할 수 있습니다(리소스 소모 / 예기치 않은 상태; 공격자가 해당 서버에 대한 접근 권한을 얻지는 않음)./hub/accept-share — 공격자가 자신의 서버를 공유할 권한이 있는 JupyterHub 사용자인 경우, 피해자에게 공유 수락을 강제하여 피해자에게 공격자의 서버 접근 권한을 부여할 수 있습니다(추가 사회공학 / 데이터 드롭 시나리오를 위한 준비 단계).Sec-Fetch-Mode를 출처 판별 기준으로 사용하는 것은 건전하지 않습니다. no-cors가 동일 출처를 의미하지는 않습니다. 5.4.5의 수정 사항은 no-cors를 동일 출처로 신뢰하지 않도록 변경했습니다. 즉시 업그레이드할 수 없는 운영자는 리버스 프록시에서 Sec-Fetch-Mode: no-cors를 포함한 요청을 차단할 수 있습니다.
poc/csrf_spawn.html — 임의의 공격자 출처에서 호스팅하고 로그인된 JupyterHub 사용자가 열도록 합니다. 자동 제출 폼이 /hub/spawn으로 교차 출처 POST를 발생시키며(브라우저가 Sec-Fetch-Mode: no-cors 전송), 취약한 빌드는 유효한 _xsrf 토큰 없이 이를 수락하고 피해자의 서버를 시작합니다. 공유 수락 변형의 경우 action을 /hub/accept-share로 지정합니다.
1. Edit TARGET-JUPYTERHUB in poc/csrf_spawn.html
2. Serve the file from an attacker origin (any static host)
3. Open it in a browser already authenticated to the target Hub
4. Observe the victim's server spawn with no XSRF token supplied
책임 있게 공개되었습니다. PoC는 수정 사항 배포 후 게시되었습니다.