Using iframe for rendering user provided html code - javascript

I want to embed user provided HTML code in my website. The code will be self-contained, and will contain script and style tags. I am planning to block all network calls from the the provided HTML code by using Content Security Policy headers. The code will only be able to access standard libraries like jquery and other standard resources (the same will be specified in the CSP). I want to restrict any communication between the iframe content and the parent domain.
My plan is to use an <iframe> to embed the content. The user will give an input, and then on clicking a button, an iframe will be rendered with the given input snippet. It will be rendered inline with other content of the page.
I am concerned about the effect of this on the security of my website.
Can I make the origin of the iframe null? Or will I have to host my content on a separate domain so that SOP blocks all the network calls to the parent page?
Will I be able to set up CSP for the iframe separately? If yes, can anyone suggest what all attributes the CSP should have?
Can I take the input html and inject it directly to my iframe from the parent page?
If there are other alternatives which don't use iframe, which are those?

Can I make the origin of the iframe null? Or will I have to host my content on a separate domain so that SOP blocks all the network calls to the parent page?
You can make the origin of the iframe null if you'll use, for instance, a data:-Url. This will prevent cross-origin requests in modern browsers, but Content Security Policy of parent document will be inherited into iframe in all browsers.
In this case some old browsers (Firefox/WinXP) will spread CSP from the iframe to parent document too.
Will I be able to set up CSP for the iframe separately? If yes, can anyone suggest what all attributes the CSP should have?
You are able to set separate CSP for iframe only if it's loaded via network scheme (http:/https:) - it will be created isolated browsing context. If non-network schemes (data:, blob:, etc) iframe will inherit CSP of parent document.
In case of isolated browsing context you can use any "attributes the CSP" what you need for your specific case.
Pay attention to csp=, sandbox= attributes, these can be useful.
Can I take the input html and inject it directly to my iframe from the parent page?
This is contravert your statement: "I want to restrict any communication between the iframe content and the parent domain.".
Therefore all communications are possible via server only.
If there are other alternatives which don't use iframe, which are those?
Isolated browsing contexts can be created via <object>/<embed>, but these are not useful in your case.

Related

Recommended method to prevent any content inside iframe from setting cookies

I get the content to be put inside an iframe from a source I do not trust. For a particular need to be met, I want the content (which might include javascript) to be unable to set cookies at all. What is the recommended method to achieve that?
Edit: I recognize this is similar to this question. I should have mentioned this earlier, but the iframe has a cross-origin source. I want to disable the content inside from setting cookies even on its own source. Does sandboxing achieve that? Thanks.
The short answer:
The HTML5 sandbox attribute prevents an iframe from reading/writing cookies. This is true for both same-origin and cross-origin iframes.
The allow-scripts attribute enables JavaScript but does not interfere with restrictions on cookies.
<iframe sandbox="allow-scripts" src="..."></iframe>
The long answer:
So if you're not fully convinced, this one is for you...
According to the W3C Working Draft (2010) and W3C Recommendation (2014), when the user agent (browser) parses the sandbox attribute, it has to add certain flags, which are then used to put restrictions on the content within the iframe. One of those flags are meant to force the content into a unique origin, and prevent it from reading/writing cookies:
The sandbox attribute, when specified, enables a set of extra restrictions on any content hosted by the iframe.
While the sandbox attribute is specified, the iframe element's nested browsing context must have the flags given in the following list set.
...
...
The sandboxed origin browsing context flag, unless the sandbox attribute's value, when split on spaces, is found to have the allow-same-origin keyword set
This flag forces content into a unique origin, thus preventing it from accessing other content from the same origin.
This flag also prevents script from reading from or writing to the document.cookie IDL attribute, and blocks access to localStorage. [WEBSTORAGE]
When a sandboxed iframe attempts to write a cookie, the following exception is raised:
Uncaught DOMException: Failed to set the 'cookie' property on 'Document': The document is sandboxed and lacks the 'allow-same-origin' flag.
and no cookie is ever written.
Since the sandboxed iframe cannot write cookies at all, it will not be able to set cookies even on its originating site.
(In fact, this would be one of the use-cases for using the allow-same-origin keyword).
The allow-same-origin attribute is intended for two cases.
...
Second, it can be used to embed content from a third-party site, sandboxed to prevent that site from opening popup windows, etc, without preventing the embedded page from communicating back to its originating site, using the database APIs to store data, etc.

Display full links within cross domain iframe

I've read about the cross-domain policy and the restrictions it has in terms of access when we don't have access to both parent and child domains in order to allow access.
However, I was wondering if I have access to parent page and not child page of the iframe is it still impossible to get the iframe to display all links within as href links like http://example.com and not example?
I've seen some scripts before but these are all server side and the links within the iframe are adjusted based on user's country so these scripts don't serve my purpose
All help appreciated

Restrict or prevent iframe navigation

I have a top page which contains an iframe with untrusted content. I am hosting the untrusted content on a domain that I control, and can (in theory) make changes to it. Short of analyzing the source code with something like Google Caja, is there any way that I can prevent the untrusted content from navigating the frame itself to other URLs? (or ideally restrict it to the trusted domain)
Related, but not quite:
Only addresses anchor tags, not navigation in general
Lots and lots of webpages talking about sandbox with "allow-top-navigation". Doesn't help because I want to restrict navigation of the frame itself
Background: My goal is to allow untrusted content to run in the iframe and to pass some user data to it, but I don't want the untrusted content to turn around and send this data to a 3rd-party. (The content will be allowed instead to postMessage any results to an API exposed by the parent window.) Content Security Policy HTTP headers on the untrusted content allow me to restrict all manner of network requests except navigation.
I randomly saw this new Content Security Policy option hinted at on MDN (with a little flask on it, so may still be experimental...)
navigation-to
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy

Cross-domain JavaScript iFrame-parent access blocked

I'm designing some "add-on" to certain websites, which should be embedded in them as an iframe. Inside this iframe there is a clickable button aimed at changing the iframe's position within the parent website.
Since things are done in coordination with the parent website, I am able to add some code there as well. However it seems I am not able to do neither of the following (one of them should suffice):
From the iframe, access data within the parent.document, in order to move the iframe to the desired position.
From the parent website, access data within the iframe, in order to check when the button is clicked.
Both typically produce an error: "Blocked a frame with origin XXX from accessing a frame with origin YYY. Protocols, domains, and ports must match".
Any advice (preferably with code sample) is appreciated.
After doing lots of searching around, I came across this:
http://www.codeproject.com/Tips/585663/Communication-with-Cross-Domain-IFrame-A-Cross-Bro
I actually tested the method (using my own short piece of code) and it seemed to work on Chrome, Firefox and IE. Now I'm gonna try the "real" implementation...
From what I understand based on the information you've provided in your question, cross domain scripting is not possible. What you would need to do is provide a script that the parent-level website can paste into their template/html and run from their domain, similar to how Google does with their analytics system.
As an alternative, try turning your iframe content instead, into a div loaded with the response from a service call made from the parent domain to the iframe domain. You would most likely need to create an API that a requesting site can use. Simply call that URI with whatever parameters you would use when referencing the page you wanted to load in the iframe, and have the script that you run on the parent website handle all the DOM alterations you want to achieve.

How does Facebook's Like Button have cross-domain access to add HTML to the parent window?

Disclaimer: I'm going to do my best to explain what I'm after, but I have pretty limited knowledge about cross-domain policies. I have searched around Stack, but if there's an answer I missed, please let me know.
We implemented the standard Facebook Like/Send button on our site. The Like and Send buttons live inside an iFrame pointing to facebook.com.
When you click on the Send button, HTML is appended as a sibling of the Facebook iFrame (ie. to our DOM).
What I want to know is how FB was able to add HTML to their div on our site without violating cross-domain policies.
Here's my fiddle. To see what's happening, inspect the DOM while clicking Send.
Thanks to #CBroe for pointing me toward the answer:
via Mozilla
window.postMessage is a method for safely enabling cross-origin communication. Normally, scripts on different pages are only allowed to access each other if and only if the pages which executed them are at locations with the same protocol (usually both http), port number (80 being the default for http), and host (modulo document.domain being set by both pages to the same value). window.postMessage provides a controlled mechanism to circumvent this restriction in a way which is secure when properly used.
Because you add send button with javascript, not with iframe. Iframe is producing when your page is loading/just after loaded.
Since this reason script is able to reach your and Iframe's content and DOM elements and edits them. As you know and mentioned, iframe cannot reach it's parent anyway.

Categories

Resources