Open Gozala opened 5 years ago
I believe we have decided to allow service workers to control sandboxed iframes with allow-same-origin
. As you say, though, the implementations have not all caught up to this decision.
Also, we have previously decided that about:srcdoc and about:blank should inherit their controller from the parent context. This is implemented in firefox, but not in chrome so far. Not sure about other browsers.
Also, we have previously decided that about:srcdoc and about:blank should inherit their controller from the parent context. This is implemented in firefox, but not in chrome so far. Not sure about other browsers.
Do you mean srcdoc
/ about:black
+ allow-same-origin
or is later not required ? In my experience Firefox (Nightly) as other browsers don't seem to do that nor with allow-same-origin
nor without. Do you by chance have tracking bug for it I can try followup there.
If allow-same-origin
is required for srcdoc
that does not address use described (quoting below):
On a related note I would like to make a case for
<iframe sandbox> + SW
combination that would allow embedded to control networking of the embedded document, where embedder and embedded document are from the same origin & withoutallow-same-origin
. (maybe that's what srcdoc should do ?)The use case being - Site wishes to load user uploaded content even if offline (think jsfiddle or dropbox). However site also doesn't trust uploaded content enough to share origin & storage / permissions shared across them.
Is this a good place to make a case for it ?
Sorry, I misunderstood. I thought you meant an unsandboxed about:srcdoc iframe. Of course, the unsandboxed case would have to work before they could work in the sandboxed case with allow-same-origin
.
Sorry, I misunderstood. I thought you meant an unsandboxed about:srcdoc iframe. Of course, the unsandboxed case would have to work before they could work in the sandboxed case with
allow-same-origin
.
Got it! Indeed unsandboxed iframes to delegate to SW work in Firefox.
It seems weird to me that srcdoc
with sandbox
but without allow-same-origin
can bypass the service worker. Do you recall why that was decided that way?
Doesn't a srcdoc with sandbox but without allow-same-origin
get an opaque origin?
It does.
Then it must not be controlled by a service worker with a different origin. Its not so much a "bypass" as creating a context in a different origin.
Well, but it's one entirely controlled by the embedder. Why should the embedder not get to control the networking too?
We have no precedent for a cross origin service worker. That would complicate a lot of security checks in implementations. I personally would be opposed to doing that. I guess we've never explicitly discussed that situation before.
Also, the embedder is still in control. They can simply not use the sandbox attribute. By using sandbox without allow-same-origin they are saying they don't trust the content of what they are going to be loading in that context and I don't think we should give it access to the service worker.
Oh right, I guess there are a bunch of subtleties I had not fully considered. I was only thinking about network requests (which would also be a different enough to maybe be a problem), but message access and such would indeed be bad.
By using sandbox without allow-same-origin they are saying they don't trust the content of what they are going to be loading in that context and I don't think we should give it access to the service worker.
But it also implies that entrusted content can conspire with server endpoint. While with allow-same-origin
it can effectively do whatever it's pleased to (assuming it's on same origin).
Oh right, I guess there are a bunch of subtleties I had not fully considered. I was only thinking about network requests (which would also be a different enough to maybe be a problem), but message access and such would indeed be bad.
That is a good point, in the use case I'm trying to outline embedded untrusted content should not have access to SW registration nor it should be able to exchange messages.
I know I'm repeating this, I appologize, what is the best way to make a case for this. Today there is no way for PWA to load untrusted content, not offline at least. There is also growing number of use cases in P2P space that would drastically benefit from a way to do so IPFS, Dat, SSB, webtorrent, blockstack, zeronet to enumerate few.
No worries, I suspect what's needed is
Hi, I would similarly also like to indicate support for this feature.
We wish to be able to load arbitrary and untrusted html/css/js into a iframe. I want protection from spectre et. al. attacks and also from javascript execution escaping from the confines of the iframe. The limitation that it is not possible to intercept requests from an iframe if allow-same-origin sandbox is NOT set is a huge deal for us. The scenario is a E2E encrypted web application where html/css/js resources are decrypted locally. I then wish to display them inside a sandboxed iframe.
I have created a POC at: https://kevodwyer.github.io/sandbox/ Hopefully that explains the flow and the issue.
This behaviour has come up in discussions on various use cases in the following issues: VS code web view - 1437 web mail - 765
Have there been any more thoughts or development on this issue? Is there any way to help move this forward?
One other alternative that came to my mind was to try and not shoehorn things onto sandboxed iframe but rather consider solution for loading sandboxed web applications with some networking capabilities. Which could possibly manifest something like:
<iframe sandbox srcworker="./service.js" />
Idea being that sandbox could load all of it's content by fetching it from service worker provided by ./service.js
. That would allow embedder to fully control CSPs.
Indeed, for protection from spectre et al I'm told we should be using COOP and COEP as well as CSP sandbox - this way we are protected in browsers that don't have out-of-process-iframes as well. However that approach seems to suffer exactly the same problem as here, not being able to serve sub assets from a service worker for a unique origin.
The srcworker idea should work in that case too I believe if it is implemented.
Is there currently any solution to have a single service worker registered at the window level (top) and have access to the "fetch" events inside iframes (of any kind)? Or to put it another way: Why aren't the fetch events triggered for iframes without a src attribute?
I've tried using iframes without a src attribute but with no luck (including with sandbox="allow-same-origin allow-scripts"). The src attribute must be a real URL, meaning it needs either a SW interceptor or a real html page from the server. Blob URLs as well as srcdoc attributes don't contribute to the fetch event in the main service worker. Also the URL must be on the same domain for the fetch events to start working for iframes. One other thing to mention is if the parent script tries to open the iframe document to write something:
iframe.contentDocument.open(); iframe.contentDocument.write('hi mom'); iframe.contentDocument.close();
The fetch events will be ignored even if the src attribute is set with a valid URL.
Why aren't the fetch events triggered for iframes without a src attribute?
You are running into implementation bugs. The parent service worker should be inherited for about:blank, srcdoc, and blob URL iframes. For example, the relevant chromium bug is:
I think firefox is the only browser that does any inheritance of the service worker in these cases at the moment.
One other alternative that came to my mind was to try and not shoehorn things onto sandboxed iframe but rather consider solution for loading sandboxed web applications with some networking capabilities. Which could possibly manifest something like:
<iframe sandbox srcworker="./service.js" />
Idea being that sandbox could load all of it's content by fetching it from service worker provided by
./service.js
. That would allow embedder to fully control CSPs.
need this feature。
FWIW, I can't get the following setup work in either browser (Chrome 96.0.4664.55 / Firefox 94.0.2 ):
<iframe
title="frame"
srcDoc="<script>fetch('/resource').then(res => res.json()).then(console.log)</script>"
sandbox="allow-same-origin allow-scripts"
></iframe>
<!-- register the worker here... -->
<script>
navigator.serviceWorker.register('./sw.js')
</script>
The GET /user
request is never propagated to the parent worker (the "fetch" event listener does not get called). I confirm that the worker registration is successful (this surfaces as a part of https://github.com/mswjs/msw/issues/1006, we've got the worker registration thoroughly tested).
@wanderview, given that you state this should function in Firefox, do you see any mistakes I'm doing with the setup above?
The service worker needs to be controlling the page before you create the about:srcdoc iframe. That means both registered and controlling. So registered before the page loaded or the SW called clients.claim().
Thank you, @wanderview. So it may be a race condition between sw registration and creating an iframe. I will try that.
I create a demo which sw proxy the requests in Iframe, which may fit the sandbox feature. https://service-worker-demo-yrobot.vercel.app/ this is the demo repo: https://github.com/Yrobot/serviceWorker-demo
Hi,
It seem today implementations across major browsers do not seem to delegate request from the document inside
<iframe sandbox="allow-same-origin" src="./inner" />
to the SW controlling the embedded even if it falls under the same scope. Same is true ifsrcdoc
is used.From what I can tell spec does not seem to specify behavior here & intuitively I would expect that to behave differently from what implementations seem to converge on.
On a related note I would like to make a case for
<iframe sandbox> + SW
combination that would allow embedded to control networking of the embedded document, where embedder and embedded document are from the same origin & withoutallow-same-origin
. (maybe that's what srcdoc should do ?)The use case being - Site wishes to load user uploaded content even if offline (think jsfiddle or dropbox). However site also doesn't trust uploaded content enough to share origin & storage / permissions shared across them.
I believe some setup like
<iframe sandbox service-worker="./service.js" src="./inner">
could be an effective way to provide such behavior.