Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider an alternative strategy for media that does not rely on media elements directly #33

Open
anforowicz opened this issue Apr 1, 2022 · 8 comments
Labels

Comments

@anforowicz
Copy link
Collaborator

To allow range responses (206 HTTP status code) ORB remembers URLs of earlier responses that sniffed as audio/video. This works under an assumption that a middle-of-resource range responses are always preceded by a first-bytes response.

I am opening this bug as a heads-up, to point out that we've seen telemetry reports from Chrome that indicate that our earlier implementation of ORB blocked some 206 responses with video/mp4 MIME type. The only explanation I can think of for such reports, is that they represent middle-of-resource range response that hasn't been marked earlier as an allowed URL. The nature of the telemetry makes it difficult to quantify these reports - they were relatively low in volume, but non-zero (and sufficiently high to show up in our reports - this was the top case where ORB blocked a response and CORB didn't).

For now, I'll tweak Chrome's ORB implementation to allow any response with an audio/video MIME type. I understand that this is undesirable in the long-term (given the discussion in #3 (comment)), but in the short-term I want to minimize the risk of shipping ORB v0.1 in Chrome.

@annevk
Copy link
Owner

annevk commented Apr 5, 2022

In principle I suppose a server could reply to a range 0- request with a non-first-byte response and only give more data upon subsequent requests. If we can enforce the MIME type for such responses it might not be too bad however.

@anforowicz
Copy link
Collaborator Author

The current hypothesis for the observed data is that there are 2 same-origin frames, each with a <video> element pointing to the same video file. Each of the 2 frames will have a separate URLLoaderFactory where ORB state is stored (e.g. storing a set of safe URLs that have been previously sniffed as video files). OTOH, the 2 frames will share some network caches (since the frames are same-origin + part of the same page). Given this, the following sequence of steps can cause one ORB instance to miss the request for the first few bytes of the video:

  • Frame1 requests first bytes of the video resource.
    • This populates stores the video URL in the 1st instance of ORB
    • This also populates network caches (some of which are checked before going through URLLoaderFactory)
  • Frame2 requests first bytes of the video resource.
    • This request is fullfilled from the network cache, without going through URLLoaderFactory and/or the 2nd instance of ORB
  • Frame2 requests middle bytes of the video resource.
    • This request goes through URLLoaderFactory and the 2nd instance of ORB.
    • ORB will block this request because the 2nd instance of ORB didn't store the video URL as safe. We are guessing that this is the step that Chromium's telemetry would report as a 206, video/mp4 response that gets blocked by ORB

@annevk
Copy link
Owner

annevk commented Apr 21, 2022

I see, that does seem tricky to resolve. The safelisted URLs would have to be cached somehow in the ORB layer. And perhaps you can "refcount" the media elements by incrementing and decrementing a number in that cache to ensure cleanup. (This essentially goes back to our earlier design.)

(We could make ORB operate on HTTP cached resources as well, but I suppose the "memory cache" might come into play here as well at which point that would not be a solution as that's in the same process as the attacker.)

cc @farre

@annevk
Copy link
Owner

annevk commented May 17, 2022

@anforowicz what do you think about the idea? Is that in line with the changes you were thinking of making here?

@annevk annevk added the mvp label May 17, 2022
@anforowicz
Copy link
Collaborator Author

I haven't really thought much about what can be implemented beyond ORB v0,1 in Chrome.

In terms of the spec, we can either:

  • Ignore this problem as an implementation detail (e.g. ignore Spectre and/or compromised content/renderer processes and just say that the media element keeps track of its requests - this is what we've discussed earlier in Improve logic for media elements #16 (comment)).
  • Suggest that there each NIK has only a single store of safe/validated media URLs. I am not really sure how feasible this is implementation-wise (in Chrome, or in Firefox).

@annevk
Copy link
Owner

annevk commented May 18, 2022

@anforowicz I'm confused, doesn't this issue suggest we cannot use the first of these options?

@anforowicz
Copy link
Collaborator Author

doesn't this issue suggest we cannot use the first of these options?

If we trust the medial element to correctly report initial-VS-subsequent media request state, then everything seems to work fine. In particular, I don't see any step in the current ORB algorithm that would misbehave just because a certain request was missed by ORB (e.g. because it was fulfilled from a cache).

Missing the initial media request seems only to be an issue if an ORB implementation doesn't trust the media element and wants to verify itself the initial-VS-subsequent media request state (e.g. by tracking URLs that sniffed as media when their first bytes were requested).

Maybe I am missing something?

@annevk annevk changed the title Not all range responses are preceded by a first-bytes response Consider an alternative strategy for media that does not rely on media elements directly May 21, 2022
@annevk annevk added future and removed mvp labels May 21, 2022
@annevk
Copy link
Owner

annevk commented May 21, 2022

Yeah, I think you're right. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants