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

Support mixed-content opaque stream fetches #56

Closed
wolenetz opened this issue Sep 2, 2015 · 26 comments
Closed

Support mixed-content opaque stream fetches #56

wolenetz opened this issue Sep 2, 2015 · 26 comments

Comments

@wolenetz
Copy link

wolenetz commented Sep 2, 2015

Mixed Content[1] already indicates that the following are optionally-blockable:
video loaded via <video> or <source>
audio loaded via <audio> or <source>

MSE extends the loading functionality of both <video> and <audio> to let applications provide the media via buffers and streams. The typical mechanism for appending buffers to <video> or <audio> using MSE involves XHRs, which are "blockable" per the mixed content spec [1]. However, if opaque streams were used to provide the loaded video or audio to <video> or <audio> using MSE's appendStream() API, then MSE would not be outright "blockable" in a mixed content application scenario, extending the viability of using MSE to applications who wish to have their origin secure but are not ready yet for the content to be secure.

[1] https://w3c.github.io/webappsec/specs/mixedcontent/

In particular, Fetch needs to support opaque responses by yielding an opaque stream. This bug tracks discussion and specification of this.

(Updated May 24, 2016 to show <audio> and <video> correctly with markdown.)

@yutakahirano
Copy link
Owner

Does that mean an opaque response's body property should be an opaque stream?

I think "opaque stream" itself will be defined in the streams spec - Is that correct, @domenic, @tyoshino?
In the fetch spec, we should define isUsed / isDisturbed on opaque responses. Is there anything I'm missing?

@annevk
Copy link

annevk commented Sep 4, 2015

Does that mean an opaque response's body property should be an opaque stream?

I think that's basically the suggestion, yes. It's not clear to me all browsers are on board with this plan, but that's the proposal from Google. At the moment though Fetch would return null for body on opaque responses.

@yutakahirano
Copy link
Owner

+@wanderview fyi

@wanderview
Copy link

Is there any definition of what an opaque stream is? Its hard to understand what this issue is asking for without at least a sketch of the opaque stream behavior.

Wouldn't an alternative be to allow MSE consume Response objects directly? You could then pass an opaque Response directly to MSE.

@yutakahirano
Copy link
Owner

@wolenetz, can you answer @wanderview's question?

@yutakahirano
Copy link
Owner

https://w3c.github.io/webappsec-credential-management/#monkey-patching-fetch-2 adds "opaque" flag to Request, but I think opaque streams can be used for such a case, too. @mikewest, what do you think about it?

@wanderview
Copy link

I would still like some definition of what an "opaque stream" is.

@wanderview
Copy link

From IRC:

12:19 PM wanderview: btw, opaque stream is basically a stream for all intents and purposes but only privileged code (read: the user agent) gets to see the bytes
12:21 PM wanderview: and thank you in advance for the review
12:24 PM → encryptd_fractal joined (~encryptd_@156.39.191.244)
12:24 PM annevk: this seems to create a whole new vector of opaque tainting to be implemented...
12:25 PM ⇐ yoav quit (~yoav@sdo26-1-78-245-148-181.fbx.proxad.net) Remote host closed the connection
12:25 PM annevk: pass an opaque stream to a DOM implemented decoder, and the decoder has to produce an opaque stream, right?
12:25 PM etc, etc
12:30 PM <yhirano_> wanderview: what do you mean by "a DOM implemented decoder"?
12:31 PM yhirano_: like if https://encoding.spec.whatwg.org/ grew support for streams... it would in theory be a transform
12:31 PM yhirano_: yet, if it took an opaque stream it would now have to be smart enough to pass on the opaqueness, etc
12:32 PM yhirano_: maybe we need this, but it seems to add some non-trivial complexity
12:33 PM yhirano_: for example, var r = new Response(url, { body: anOpaqueBody }) gives a non-opaque Response with an opaque body... that has to be propagated through Cache, etc...
12:33 PM <yhirano_> wanderview: Body.text() and so on don't recognize opaque streams. I thought it would be similar for other decoders
12:35 PM yhirano_: well I guess thats the question... what recognizes these things and what doesn't... its hard to tell from the current spec issue
12:38 PM <yhirano_> wanderview: agreed.

@wanderview
Copy link

If we allow opaque streams, then this would need to fail:

addEventHandler('fetch', function(evt) {
  if (evt.mode === 'navigate') {
    evt.respondWith(fetch(crossSiteURL, { mode: 'no-cors' }).then(function (response) {
      // Create a synthetic non-opaque response with an opaque body?
      var laundered = new Response(response.body);
      return laundered;
    })
  }
});

And probably lots of other opaque tainting issues to be discovered.

@tyoshino
Copy link
Contributor

tyoshino commented Nov 5, 2015

wolenetz explained thoughts on appendRespones() vs. appendStream() in this post to public-webappsec:
https://lists.w3.org/Archives/Public/public-webappsec/2015Apr/0105.html

@annevk
Copy link

annevk commented Nov 5, 2015

If that is really the only use case, appendResponse() would be much simpler.

@tyoshino
Copy link
Contributor

tyoshino commented Nov 5, 2015

One point I'm not sure yet is, ... it seems to me that opaqueness for CORS and MIX (here) are slightly different. Opaqueness for CORS response tainting must be strict so that no one can uncover the contents which the server didn't allow to provide to cross-origin scripts. Opaqueness for MIX is protecting developers from easily using unreliable (possibly forged) subresource, and so the wall doesn't have to be high as one for CORS, right?

Can we really converge these different opaqueness concept and protect by single opaqueness flag (the requirement for CORS is stronger so we can use it for MIX too)? Won't we want to distinguish them in the future?

If that is really the only use case, appendResponse() would be much simpler.

Yea... I also agree with yhirano's point about possible composition of streams to process bytes without right to read the actual bytes.

We were also discussing how to implement equivalent of "img.src=URL.createObjectURL(blob)" for streams.

We initially sketched it like:

var writableStream = img.srcWithStream();
var writer = writableStream.getWriter();
...

But e.g. to make it able to use no-cors results, someone said maybe it should be img.setResponse(response) instead, IIRC.

@annevk
Copy link

annevk commented Nov 5, 2015

I'm not sure what you mean by opaqueness for CORS. A "cors" response has very limited opaqueness (just around headers). If you mean "no-cors", i.e. cross-origin resources without CORS, those are equivalent to MIX, since both are cross-origin. MIX is worse of course, since it's a worse legacy security bug that is hard to get rid of.

(As for <img>, I think we want something similar to what we already have for <video> and such, srcObject, and have that accept responses, e.g., <img>.srcObject = response. It cannot be just a stream since <img> needs to know about the Content-Type header too, for SVG.)

@tyoshino
Copy link
Contributor

tyoshino commented Nov 5, 2015

I'm not sure what you mean by opaqueness for CORS. A "cors" response has very limited opaqueness (just around headers). If you mean "no-cors", i.e. cross-origin resources without CORS, those are equivalent to MIX,

Yes, no-cors. Sorry for being unclear.

since both are cross-origin. MIX is worse of course, since it's a worse legacy security bug that is hard to get rid of.

Ah! I see. I was unaware of that... Thanks

@tyoshino
Copy link
Contributor

tyoshino commented Nov 5, 2015

(As for , I think we want something similar to what we already have for

I see. When composing an image from byte stream and type provided separately, maybe we just create a Response just for holding them? Hmm, it sounds natural as I guess most of elements we may want to stream data into via Streams are currently taking a URL (src=) and "fetch"-ing it. OK.

@tyoshino
Copy link
Contributor

tyoshino commented Nov 5, 2015

BTW, as yhirano mentioned in #56 (comment), there is another opaqueness being developed for Credential Management.

I was comparing the opaqueness for response (discussed in this issue) and that for analyzing possible merge/confusion/etc. in the future. I found that the opaqueness for Credential Management is kinda weak than one for response, currently (in terms of e.g. w3c/webappsec#241 (comment) and w3c/webappsec#241 (comment)). This is still subject to change if needed? E.g. making the opaqueness propagated to SW, aligning XHR/Fetch with toFormData() by requiring XHR/Fetch to comare environment's origin and FormData's origin (currently not embedded) before issuing a request.

@annevk
Copy link

annevk commented Nov 5, 2015

whatwg/fetch#49 is about adding srcObject to more elements and supporting assigning Response to it.

I think @mikewest has not settled on the exact design of credential management opaqueness and is probably open to changes.

@wolenetz
Copy link
Author

Getting back to the MIX MSE need for opacity in some form of API, I'm not quite clear on the relative difficulties to FETCH, STREAMS, and any opaque-tainting details of doing opaqueStream vs opaqueResponse. IIUC, MSE MIX (w3c/media-source#22) needs:

  1. secure-origin'ed web app ability to fetch from insecure origin a stream with an optional limit on maximum number of bytes to fetch
  2. prevention of that web app from seeing the contents of the response
    2a) I'm not clear what other Response object attributes might also need to be hidden from the web app in this MIX fetch case. Headers?
  3. ability for the web app to provide the stream (or response) to a SourceBuffer.append{Response or Stream} method.
  4. Upon SourceBuffer.append{Response or Stream} invocation, the UA must be able to become the exclusive reader of the fetched media stream (this is really a requirement on the non-opaque STREAM + FETCH that is inherited by the opaque version).

I would like to find a route to enabling MIX MSE, and would appreciate your expert guidance here.

@annevk
Copy link

annevk commented Apr 1, 2016

secure-origin'ed web app ability to fetch from insecure origin a stream with an optional limit on maximum number of bytes to fetch

That breaks the same-origin policy. I don't think that's acceptable. You can only have complete responses of which you expose close to nothing to the API user.

@yutakahirano
Copy link
Owner

Note: the "opaque" body I mentioned at #56 (comment) was removed.

@yutakahirano
Copy link
Owner

Regarding mixed-content , we can make a fetch for a mixed-content resource by specifying request's type to "video". Is it acceptable to create a request with a user-provided type, with some restrictions such as prohibiting cors mode?

@annevk
Copy link

annevk commented Apr 28, 2016

You'd also need to restrict how the response ends up being used. I'm not entirely convinced this is something we should be adding though. It's a fair amount of complexity for something that in a couple of years will all use HTTPS anyway.

@yutakahirano
Copy link
Owner

You'd also need to restrict how the response ends up being used.

Even now, we can access a Response for a request with type = "video" and mode = "no-cors" in a serviceworker. So I thought we need restrictions only in the request-side. Am I missing something?

@annevk
Copy link

annevk commented Apr 28, 2016

If you could do it on a page, you could circumvent CSP restrictions.

@yutakahirano
Copy link
Owner

I see, thank you.

@annevk
Copy link

annevk commented Jan 17, 2017

This never really went anywhere. I doubt it would still be accepted as it's somewhat of a security regression in ways. Close?

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

No branches or pull requests

5 participants