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

<iframe sandbox /> + SW #1390

Open
Gozala opened this issue Feb 19, 2019 · 24 comments
Open

<iframe sandbox /> + SW #1390

Gozala opened this issue Feb 19, 2019 · 24 comments

Comments

@Gozala
Copy link

Gozala commented Feb 19, 2019

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 if srcdoc 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 & without allow-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.

@wanderview
Copy link
Member

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.

@Gozala
Copy link
Author

Gozala commented Feb 19, 2019

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 & without allow-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 ?

@wanderview
Copy link
Member

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.

@Gozala
Copy link
Author

Gozala commented Feb 19, 2019

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.

@annevk
Copy link
Member

annevk commented Feb 20, 2019

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?

@wanderview
Copy link
Member

Doesn't a srcdoc with sandbox but without allow-same-origin get an opaque origin?

@annevk
Copy link
Member

annevk commented Feb 20, 2019

It does.

@wanderview
Copy link
Member

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.

@annevk
Copy link
Member

annevk commented Feb 20, 2019

Well, but it's one entirely controlled by the embedder. Why should the embedder not get to control the networking too?

@wanderview
Copy link
Member

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.

@annevk
Copy link
Member

annevk commented Feb 20, 2019

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.

@Gozala
Copy link
Author

Gozala commented Feb 20, 2019

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.

@annevk
Copy link
Member

annevk commented Feb 20, 2019

No worries, I suspect what's needed is

  • Some kind of indication of demand for this kind of feature
  • Interest from implementers to support it if the various tradeoffs can be worked out in a satisfactory manner
  • A precise enumeration of where changes would need to be made and what the implications of those changes will be
  • A complete test suite

@kevodwyer
Copy link

kevodwyer commented Dec 30, 2019

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

@ianopolous
Copy link

Have there been any more thoughts or development on this issue? Is there any way to help move this forward?

@Gozala
Copy link
Author

Gozala commented Jun 10, 2020

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.

@ianopolous
Copy link

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.

@dispeakble
Copy link

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.

@wanderview
Copy link
Member

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:

https://crbug.com/880768

I think firefox is the only browser that does any inheritance of the service worker in these cases at the moment.

@Rainmen-xia
Copy link

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。

@kettanaito
Copy link

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 mswjs/msw#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?

@wanderview
Copy link
Member

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().

@kettanaito
Copy link

Thank you, @wanderview. So it may be a race condition between sw registration and creating an iframe. I will try that.

@Yrobot
Copy link

Yrobot commented Feb 28, 2023

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

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

9 participants