OFFSITE.DARK
← Signals

Jun 19, 2026

3 min

Sploitus

  • jupyterhub
  • csrf
  • xsrf
  • cve
  • jupyter

news

JupyterHub CSRF XSRF Bypass (CVE-2026-40864)

Sec-Fetch-Mode: no-cors misclassified as same-origin bypasses XSRF on /hub/spawn and /hub/accept-share; PoC indexed on Sploitus.

Summary

CVE-2026-40864 is a cross-site request forgery (CSRF/XSRF) flaw in JupyterHub 4.1.0 through 5.4.4. XSRF protection (reworked in 4.1.0) incorrectly treated requests carrying Sec-Fetch-Mode: no-cors as same-origin, allowing cross-origin HTML form POSTs to bypass token checks on form endpoints. Sploitus listed it in Exploits of the week as Exploit for Cross-Site Request Forgery (CSRF) in Jupyter Jupyterhub; researcher Romain Deperne published a PoC repository referenced in the index.

OFFSITE.DARK attributes Sploitus as the weekly index source, not as exploit author.

Technical Details

JupyterHub uses _xsrf_utils.py to gate state-changing form POSTs. After 4.1.0, the framework consulted Sec-Fetch-Mode as an origin oracle, exempting no-cors requests from XSRF validation.

Problem: browsers send Sec-Fetch-Mode: no-cors for cross-origin "simple" form submissions — precisely the classic CSRF vector XSRF tokens exist to block.

EndpointMethodImpact
/hub/spawnForm POSTForce victim to spawn their single-user server
/hub/accept-shareForm POSTTrick victim into accepting attacker's shared server

The JSON API is unaffected — non-simple content types trigger CORS preflight, which still enforces XSRF.

PoC pattern (from indexed research): host an auto-submitting HTML form on an attacker origin; logged-in victim visits the page; browser sends cross-origin POST with Sec-Fetch-Mode: no-cors; vulnerable Hub accepts without valid _xsrf cookie.

VersionStatus
4.1.0 – 5.4.4Vulnerable
5.4.5+Fixed (commit 9c5ec277)

CVE

FieldValue
CVECVE-2026-40864
CWECWE-352 — Cross-Site Request Forgery
CVSS4.3–5.4 (Moderate)
AdvisoryGHSA-m68r-v472-jgq9
Disclosed2026-05-05

Impact

  • Resource abuse: unauthorized server spawns consume cluster CPU/memory quotas.
  • Share acceptance: if the attacker is a permitted JupyterHub user with share rights, forcing /hub/accept-share grants the victim access to the attacker-controlled notebook server — a setup step for credential harvesting or malicious notebook delivery.
  • No direct notebook access via spawn alone (attacker cannot read victim server without separate bugs).

Requires victim to be authenticated to JupyterHub and visit attacker-controlled content (user interaction).

Mitigation

  1. Upgrade to JupyterHub 5.4.5+ immediately.
  2. Reverse proxy mitigation: drop requests to JupyterHub carrying Sec-Fetch-Mode: no-cors until upgraded.
  3. CSP on Hub pages to reduce cross-origin form gadget embedding where compatible with your auth flow.
  4. Audit shared-server policies — restrict which users may share notebooks externally.

Sources

→ Source