Bug 90613

Summary: Inside a sandboxed iframe, it should be possible to create another iframe and access it
Product: WebKit Reporter: Bruno Michel <bruno.michel>
Component: FramesAssignee: Nobody <webkit-unassigned>
Status: UNCONFIRMED    
Severity: Normal CC: abarth, ap, ian
Priority: P2    
Version: 525.x (Safari 3.2)   
Hardware: All   
OS: All   
Attachments:
Description Flags
The first file of the test case
none
Second file of the test case none

Bruno Michel
Reported 2012-07-05 08:31:54 PDT
Created attachment 150946 [details] The first file of the test case Hi, I'm working with iframes and iframes inside iframes (probably not ideal, but I have to). In the parent window, I have an iframe with sandbox="allow-scripts". Inside it, I have a javascript that creates other iframes and load content for them by setting the src or srcdoc attributes. Just a bit latter, the same javascript tries to inspect the content of these iframes but it fails: "Unsafe JavaScript attempt to access frame with URL about:blank from frame with URL http://localhost:3000/frame.html. Domains, protocols and ports must match". I was expecting that the script run fine as it should be on the same fake domain. Of course, if I add the allow-same-origin on the sandbox property of the first iframe, it works. But it defeats the goal of using the sandbox as the sandboxed iframe can overload it. I'm not really sure that it is a bug, but as I don't understand why someone would want this behaviour, I think it's better to make a bug report and let informed people decide about it.
Attachments
The first file of the test case (195 bytes, text/html)
2012-07-05 08:31 PDT, Bruno Michel
no flags
Second file of the test case (405 bytes, text/html)
2012-07-05 08:32 PDT, Bruno Michel
no flags
Bruno Michel
Comment 1 2012-07-05 08:32:13 PDT
Created attachment 150947 [details] Second file of the test case
Adam Barth
Comment 2 2012-07-08 20:30:46 PDT
Thanks for the bug report. Our behavior matches the spec, but it might be worth changing the spec in this regard. I have an item on my TODO list to email the WhatWG, but it hasn't made it to the top of the list yet.
Ian 'Hixie' Hickson
Comment 3 2012-07-09 11:45:23 PDT
I don't know how to make this safe. We don't want to allow the sandboxed page to create an iframe that contains the parent page and then be able to manipulate it, for example. That would defeat the whole purpose of sandboxing the page. You can use postMessage() to communicate between the iframes.
Adam Barth
Comment 4 2012-07-09 13:57:37 PDT
In <http://html.spec.whatwg.org/#origin>, what would happen if we moved this statement to the top: If a Document has the address "about:blank" -> The origin and effective script origin of the Document are those it was assigned when its browsing context was created. That doesn't quite work because <iframe sandbox src="about:blank"></iframe> wouldn't get a unique origin, so we'd have to do something in that case... It's definitely messy and might not be worth the risk.
Ian 'Hixie' Hickson
Comment 5 2012-07-09 14:05:16 PDT
I don't follow what you're proposing.
Bruno Michel
Comment 6 2012-07-10 02:47:31 PDT
(In reply to comment #3) > I don't know how to make this safe. We don't want to allow the sandboxed page to create an iframe that contains the parent page and then be able to manipulate it, for example. That would defeat the whole purpose of sandboxing the page. Maybe it's just a stupid idea, but if the sandboxed page create an iframe by using the srcdoc attribute, we could allow the sandboxed page to manipulate the iframe. > You can use postMessage() to communicate between the iframes. Well, it's precisely what I was trying to avoid. Let me explain my case: we are writing an ebook reader and the ebooks can contain javascripts (useful ones for the reading of the ebook, but also unsafe ones). The ebooks are HTML files that we load in iframes and we manipulate some CSS rules on the iframe to go from one page to another (overflow: hidden, top position, etc.). If we put the sandbox flag on these iframes, we can no longer go from one page to another. A possibility is to inject javascripts in this iframe to communicate with postMessage(). But we don't control the content of the iframe and it's very difficult to have a reliable javascript in this context. Another reason (maybe a bad one) is that the reader use a library (Monocle) for moving between the pages and using postMessage() will transform some direct code to asynchronous code and it's hard to modify afterwards an existing lib in a such a way. So, I tried to add an indirection: we put only the content in the iframe and it's our reader that we sandbox. And, as our reader as to communicate with our API (to add annotations for example), it uses postMessage() with the parent page that makes the Ajax calls (after some filters).
Bruno Michel
Comment 7 2012-07-12 05:32:08 PDT
(In reply to comment #6) After reading the spec again, I think a solution could be to have 3 states for the sandboxed origin browsing context flag: - explicitly set on this iframe - inherited from the parent context - off The states 1 and 3 have the same behaviours than currently. For state 2, we allow iframes that are loaded locally to be on the same domain: javascript URL, data URL, about:blank and srcdoc iframes. In <http://html.spec.whatwg.org/#origin>, it could be somethig like: If a Document's active sandboxing flag set has its sandboxed origin browsing context flag explicitly set -> The origin is a globally unique identifier assigned when the Document is created. -> The effective script origin is initially an alias to the origin of the Document. If a Document was generated from a javascript: URL -> The origin is an alias to the origin of the script of that javascript: URL. -> The effective script origin is initially an alias to the origin of the Document. If a Document has the address "about:blank" -> The origin and effective script origin of the Document are those it was assigned when its browsing context was created. If a Document is an iframe srcdoc document -> The origin of the Document is an alias to the origin of the Document's browsing context's browsing context container's Document. -> The effective script origin is initially an alias to the effective script origin of the Document's browsing context's browsing context container's Document. If a Document has inherited a sandboxed origin browsing context flag -> The origin is a globally unique identifier assigned when the Document is created. -> The effective script origin is initially an alias to the origin of the Document. If a Document was served over the network and has an address that uses a URL scheme with a server-based naming authority -> The origin is an alias to the origin of the Document's address. -> The effective script origin is initially an alias to the origin of the Document. If a Document was generated from a data: URL that was returned as the location of an HTTP redirect (or equivalent in other protocols) -> The origin is an alias to the origin of the URL that redirected to the data: URL. -> The effective script origin is initially an alias to the origin of the Document. If a Document was generated from a data: URL found in another Document or in a script -> The origin is an alias to the origin of the Document or script that initiated the navigation to that URL. -> The effective script origin is initially an alias to the effective script origin of the Document or script that initiated the navigation to that URL. If a Document was obtained in some other manner (e.g. a data: URL typed in by the user, a Document created using the createDocument() API, etc) -> The origin is a globally unique identifier assigned when the Document is created. -> The effective script origin is initially an alias to the origin of the Document.
Ian 'Hixie' Hickson
Comment 8 2012-07-12 10:04:09 PDT
If you're proposing that frame A should be able to access from B but frame B should not be able to access frame A, that's basically a non-starter. It is _trivially_ easy to accidentally expose frame A to frame B, for example any time you pass a JS object from frame A to frame B you are also passing the frame A's global "Object" prototype.
Bruno Michel
Comment 9 2012-07-15 12:19:09 PDT
(In reply to comment #8) No, it's not what I'm proposing. I'm just saying that I'd like to let a sandboxed iframe create another iframe in the same sandbox (same origin and effective script origin opaque identifiers) if it doesn't use external resources for creating it (network, disk, etc.). Is it reasonable?
Note You need to log in before you can comment on or make changes to this bug.