W3C home > Mailing lists > Public > public-html-media@w3.org > February 2015

Fetch, MSE, and MIX

From: Ryan Sleevi <sleevi@google.com>
Date: Thu, 19 Feb 2015 21:06:17 -0800
Message-ID: <CACvaWvZ+b9+fU2Af9y=bUzOFv6kYmhVK3GYbdSweV8ZPZ9YoRA@mail.gmail.com>
To: whatwg@whatwg.org
Cc: "public-webappsec@w3.org" <public-webappsec@w3.org>, public-html-media@w3.org
Cross-posting, as this touches on the Fetch [1] spec, Media Source
Extensions [2], and Mixed Content [3]. This does cross-post WHATWG and
W3C, apologies if this is a mortal sin.

TL;DR Proposal first:
- Amend MIX in [4] to add "fetch" as an optionally-blockable-request-context
  * This means that fetch() can now return HTTP content from HTTPS
pages. The implications of this, however, are described below, if you
can handle reading it all.
- Amend MSE in [5] to introduce a new method, appendResponse(Response
response), which accepts a Response [6] class
- In MSE, define a Response Append Loop similar to the Stream Append
Loop [7], that calls the consume body algorithm [8] on the internal
response [9] of Response to yield an ArrayBuffer, then executes the
buffer append [10] algorithm on the SourceBuffer


MUCH longer justification why:
As it stands, <audio>/<video>/<source> tags today are optionally
blockable content, as noted in [4]. Thus, an HTTPS page may set the
source to HTTP content and load the content (although typically with
user-agent indication). MSE poses itself as a spec to offer much
greater control to site authors than <audio>/<video>, as noted in its
use cases, and as a result, has seen a rapid adoption among a number
of popular video streaming sites. Most notably, the ability to do
adaptive streaming with MSE helps provide a better quality, better
performing experience for users. Finally, in some user agents, MSE is
a pre-requisite for the use of Encrypted Media Extensions [11].

However, there are limitations to using MSE that don't exist with
<video>/<audio>. The most notable of these is that in order to
implement the adaptive streaming capabilities, most sites make use of
XMLHttpRequest to request portions of media content, which can then be
supplied to the SourceBuffer. Based on the feedback that MSE provides
the script author, it can then adjust the XHRs they make to use a
lower bitrate media source, to drop segments, etc. When using XHR, the
site author loses the ability to mix HTTPS pages with HTTP media, as
XHR is (rightfully so) treated as blocked content.

The justification for why XHR does this is that it returns the full
buffer to the page author. In practice, we saw many sites then taking
that buffer and making security decisions on it - whether it be
"clearly" bad things such as eval()ing the content to more subtle
things like adjusting UI or links. All of these undermine all of the
security guarantees that HTTPS tries to provide, and thus XHR is
blocked.

The result is that if an HTTPS site wants to use MSE with XHR, all of
the content needs to be served via HTTPS. We've already seen some
providers complain that this is prohibitively expensive in their
current networks [12], although it may be solvable in time, as
demonstrated by other video sharing sites [13].

In a choice between using MSE - which offers a better user experience
over <video>/<audio> by reducing bandwidth and improving quality - and
using HTTPS - which offers better privacy and security controls -
sites are likely to choose solutions that reduce their costs rather
than protect their users, a reasonable but unfortunate business
reality.

I'm hoping to find a way to close that gap - to allow sites to use MSE
(and potentially EME) via HTTPS documents, while still sourcing their
media content via HTTP. This may seem counter-intuitive, and a step
back from the efforts of the Chrome security team, but I think it is
actually consistent with our goals and our past comments. In
particular, this solution tries to provide a means and incentive for
sites to adopt MSE (improving user experience) AND to begin migrating
to HTTPS; first with their main document, and then, in time, all of
their media content.

This won't protect adversaries from knowing what content the user is
actively watching, for example, but will help protect other vital
assets - such as their cookies, session identifiers, user information,
friends list, past viewing history, etc.

Allowing fetch() to return HTTP content sourced from HTTPS pages seems
like it would re-open the XHR hole, but this isn't the case. As
described in [14], all requests whose mode is CORS or
CORS-with-forced-preflight are force-failed. This only leaves the
request modes of "no-cors", "same-origin", "about"and "data". Because
the origins are different between the document (https) and the request
URL (http), the request mode will be "no-cors", and thus the returned
Response object will be set to "opaque".

The "opaque" response prevents direct access to the Response data.
Similarly, the SourceBuffer object does not allow direct access to the
data - this is only passed on to the audio/video decoders, same as the
existing <audio>/<video>/<source> tags today. I realize this may
prevent access to the full capabilities of MSE; indeed, some use cases
require access to the content in order to do adaptive streaming.
However, there still seem a number of use cases where it can work, or
where existing solutions that do require direct access to content may
be adjusted, slightly, so that they don't.

In discussing this, internally and with other vendors, the primary
security implication of this is that of privacy leakage. However, this
problem exists regardless of fetch(), due to the fact that script can
always inject any of the optionally-blockable content tags into the
page and leak information. That is, I can always disclose content by
using a <video> or <img> tag directly, and I can always smuggle back a
few bits of information at a time (for example, using the width/height
of the image to smuggle back 4-8 bytes at a time, or, even more
primitively, using onload/onerror to smuggle a bit at a time back)

Further, I'm not proposing that there be any special UI handling for
these mixed-content fetch()'s - that is, they behave as the user agent
already does when encountering passive mixed content (e.g. some form
of UI warning/degradation). So performing these fetch()'s will NOT
yield positive security indicators. Of course, as proposals like [15]
mature, it may be far more desirable sites to have HTTPS with mixed
content compared to HTTP, thus making this proposal even more
attractive than the HTTP counterpart.

Overall, the hope is to provide incentives for media sharing sites to
begin migrating to HTTPS, allowing them to keep the existing features
they have over HTTP (in this case, MSE), and potentially allowing for
a migration path that allows the staged deprecation of allowing more
powerful, privacy-sensitive features like EME [16] from being
available over HTTP, while not taking any steps backwards in terms of
privacy or security for fetch() or HTTPS pages.

This is not meant to be a long-term solution for optionally-blockable
content. I absolutely think we should be working to wean sites off
this and move them away. However, in the trade-off between having
major sites using HTTP or having to prolong optionally-blockable
content for some additional, defined period of time, I absolutely
believe the latter is in the greater interest of web security, and
consistent  with the findings of the W3C's TAG.

So, beyond telling me I wrote way too much, what do people think?

[1] https://fetch.spec.whatwg.org/
[2] http://w3c.github.io/media-source/
[3] https://w3c.github.io/webappsec/specs/mixedcontent/
[4] https://w3c.github.io/webappsec/specs/mixedcontent/#category-optionally-blockable
[5] http://w3c.github.io/media-source/#sourcebuffer
[6] https://fetch.spec.whatwg.org/#response-class
[7] http://w3c.github.io/media-source/#sourcebuffer-stream-append-loop
[8] https://fetch.spec.whatwg.org/#body
[9] https://fetch.spec.whatwg.org/#concept-internal-response
[10] http://w3c.github.io/media-source/#sourcebuffer-buffer-append
[11] https://w3c.github.io/encrypted-media/
[12] https://lists.w3.org/Archives/Public/www-tag/2014Oct/0105.html
[13] https://www.youtube.com/
[14] https://w3c.github.io/webappsec/specs/mixedcontent/#should-block-fetch
[15] https://lists.w3.org/Archives/Public/public-webappsec/2014Dec/0062.html
[16] https://www.w3.org/Bugs/Public/show_bug.cgi?id=26332
[17] https://w3ctag.github.io/web-https/
Received on Friday, 20 February 2015 05:06:45 UTC

This archive was generated by hypermail 2.3.1 : Friday, 20 February 2015 05:06:46 UTC