Bug 90613 - Inside a sandboxed iframe, it should be possible to create another iframe and access it
Summary: Inside a sandboxed iframe, it should be possible to create another iframe and...
Status: UNCONFIRMED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Frames (show other bugs)
Version: 525.x (Safari 3.2)
Hardware: All All
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-07-05 08:31 PDT by Bruno Michel
Modified: 2012-07-15 12:19 PDT (History)
3 users (show)

See Also:


Attachments
The first file of the test case (195 bytes, text/html)
2012-07-05 08:31 PDT, Bruno Michel
no flags Details
Second file of the test case (405 bytes, text/html)
2012-07-05 08:32 PDT, Bruno Michel
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Bruno Michel 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.
Comment 1 Bruno Michel 2012-07-05 08:32:13 PDT
Created attachment 150947 [details]
Second file of the test case
Comment 2 Adam Barth 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.
Comment 3 Ian 'Hixie' Hickson 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.
Comment 4 Adam Barth 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.
Comment 5 Ian 'Hixie' Hickson 2012-07-09 14:05:16 PDT
I don't follow what you're proposing.
Comment 6 Bruno Michel 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).
Comment 7 Bruno Michel 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.
Comment 8 Ian 'Hixie' Hickson 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.
Comment 9 Bruno Michel 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?