Re: [w3c/ServiceWorker] cache.match() and COEP (#1490)

Yes, @wanderview is right that Firefox currently sends all the data about opaque responses to the content processes and only creates the opaque wrapped response when [processing the received IPC data](https://searchfox.org/mozilla-central/rev/23d4bffcad365e68d2d45776017056b76ca9a968/dom/fetch/InternalResponse.cpp#83), which is too late.  I think [bug 1565199](https://bugzilla.mozilla.org/show_bug.cgi?id=1565199) covers the general scenario for Firefox.

The most recent thoughts @perryjiang and I had on this were that we would run the same CORP check on cache.match() responses and at least, for now, send a pre-opaqued response that can't be used for anything.  (That is, there's just a opaque filtered response and any attempt to consume the underlying response will fail with a corp-check (network) error.)

API-wise, it seems like there are 5 options:
1. Partition storage of COEP-affected storage by the COEP bits.  A COEP-safe storage cannot store something that would fail a CORP-check.  All storages opened by COEP contexts set this bit on creation and fail to open a storage if the bit is not set.  A non-COEP context can opt in to this constraint when creating a storage.  Maybe whole storage buckets can be marked COEP-safe.  This may or may not be something that would have synergies about the proposals to give WASM memory-mapped block storage APIs so lucene and SQLite can be compiled into WASM and be fast.
2. Hide keys and Responses when the Response would fail a CORP check.  This seems untenably confusing.
3. Ben's proposed match-rejects when a matched Response fails a CORP check.  This would cause the most immediate/obvious breakage as matchAll() calls that might not look at the CORP-failing Response might now explode, although that use case seems wacky.  This approach becomes more problematic if we allow Responses to be stored in IndexedDB.  Application logic that invokes `getAll` is a thing that happens, and poisoned values would be a real problem in that case.
4. Responses become unusable even though technically if they were just a handle and you were respondWith()ing to a non-COEP context, it could work.  (Firefox's current short term plan.)  Nothing breaks until you try and consume it.
5. Responses are just a handle and can transit a COEP-context into a non-COEP-context and it should work just like the COEP-context isn't involved.  This is least breakage prone but the most complex.

The Responses-get-nulled situation is similar to Blob edge-cases where a `<input type="file">` sourced-Blob is invalidated by changes on disk.  (Or when Clear-Site-Data/privacy API's clear an origin's data and there are still (cross-origin) Blob references that only held a reference to on-disk data and didn't copy the contents out.)  It's an allegedly immutable thing that can turn out not to be there.

The Responses-are-handles situation is sorta analogous to the current MessagePort.postMessage of a SharedArrayBuffer.  Because you can never reason about what global the serialized payload will be deserialized in because the ports can always be shipped, there are cases where it's safe around to ship the data itself, and there are times when you have to be shipping around a handle.  However, in that case we fail to deserialize the entire serialized object due to the SAB.

I don't have any specific proposal other than banding together to build a gateway to a parallel universe without SPECTRE attacks.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/ServiceWorker/issues/1490#issuecomment-563450588

Received on Monday, 9 December 2019 21:35:53 UTC