diff options
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/api/webapp.py')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/api/webapp.py | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/api/webapp.py b/packages/meshbay-hub/src/meshbay_hub/api/webapp.py index 3cfb208..96b93bb 100644 --- a/packages/meshbay-hub/src/meshbay_hub/api/webapp.py +++ b/packages/meshbay-hub/src/meshbay_hub/api/webapp.py @@ -111,8 +111,30 @@ CSP = "; ".join([ "font-src 'self'", "connect-src 'self' https: wss:", "worker-src 'self'", - f"frame-src {_RECAPTCHA_SRC}", - "frame-ancestors 'none'", + # `'self'` is not decoration: the streamed-download path works by navigating + # a hidden iframe to `/_mbdl/<id>` so the service worker is asked for the + # response it is holding. Without it Chrome refuses the frame, the worker is + # never asked, and the page waits out its timeout for a download that cannot + # happen — on Firefox and Safari that is the *only* way to write a large + # file to disk, so the whole path was dead. Added when reCAPTCHA needed a + # frame, which is why nobody connected the two. + f"frame-src 'self' {_RECAPTCHA_SRC}", + # `'self'`, not `'none'`, and the difference is one same-origin iframe. + # + # The threat frame-ancestors answers is clickjacking: a *foreign* page + # framing this one and stealing clicks. `'self'` refuses every foreign + # origin exactly as `'none'` does — what it additionally allows is this + # origin framing itself, which is precisely how a streamed download works + # (a hidden iframe navigates to `/_mbdl/<id>` so the service worker is + # asked for the response it holds). + # + # Under `'none'` Firefox blocked that frame, the worker was never asked, + # and every large download waited out two 15-second timeouts and then fell + # through — on Firefox and Safari that is the only way to write a large + # file to disk. Chrome did not show it: its worker intercepts the + # navigation before the network response and its CSP are ever considered, + # which is why this looked like a Firefox-only problem for an afternoon. + "frame-ancestors 'self'", "base-uri 'none'", "form-action 'none'", ]) |