Restrict or prevent iframe navigation - javascript

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

Related

Using iframe for rendering user provided html code

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.

Dynamics, iFrames

Good day everyone.
So I have a website and I am trying to embed in an iframe a dynamics server and it keeps throwing an error something about
'Refused to display https://XXXXXXXXXXXX in a frame because it set 'X-Frame-Options' to 'deny'.
Any ideas how I can get it to work?
This happens when we try to redirect the page to a login page.
Thanks
Check X-Frame-Options hearder:
The X-Frame-Options HTTP response header can be used to indicate whether or not a browser should be allowed to render a page in a <frame>, <iframe>, <embed> or <object>. Sites can use this to avoid clickjacking attacks, by ensuring that their content is not embedded into other sites.
Based on the above statement, this is something that the 'https://XXXXXXXXXXXX' has added to the page to disallow it from being used as an <iframe>
You can see that this can even be configured globally on a web server level, to secure all the websites.
If the website is in the same domain the workaround is easier using SameOrigin value.
If you want to allow all, then just don't set the response header for the XXXXXXXX site at all (if you have access to it).

How to Load an external web page inside my one and hide some content (avoiding cross site problems)

I need to incorporate in my web application some content from an external dynamic web page on which I have no control.
Then I need to filter some of the content of this page or to hide it for presenting only the relevant part that is interesting for my use.
I need also that the scripts on the external page are still working on the source site of the loaded content without cross-site protection.
Is all that possible? How can I do it? Any code example, please?
I suppose that this can be made with JS on client side .
I work on back side and these themes are quite extraneous to me, please don't blame me.
No, it is not possible.
Browser same-origin policy is designed to prevent malicious websites from doing evil.
Same-origin Policy restricts JavaScript network access to prevent evil.
Same-origin Policy also restricts script API Access to prevent evil.
From the Docs:
JavaScript APIs like iframe.contentWindow, window.parent, window.open, and window.opener allow documents to directly reference each other. When two documents do not have the same origin, these references provide very limited access to Window and Location objects.
To communicate between documents from different origins, use window.postMessage.
— MDN Web Security Reference - Cross-origin script API access
One can not use <iframe> elements as a way to "avoid cross site problems". The Same Origin Policy was created to protect users from evil web pages.

Xpath of element on another website/cross domain

I want to get the XPATH of an element on a website (my own domain), which I got it using JavaScript code as mentioned in this answer.
Now what I want to click on button which will open a url (cross domain) window and when user click on an element on that window it's XPATH is captured.
I tried doing the same using iframe with no luck.
Now my question is there a way to get the XPATH of an element of another website/ Cross domain?
Sorry this is not possible without cooperation from the other (x-domain) site. Browsers are designed not to allow access to the DOM of x-domain documents (iframe included) for security reasons.
If you had cooperation from the other site, they could load your javascript file and then use postmessage to pass the xpath to the original page.
Other options would be to create a bookmarklet users could use on the other page, or a browser extension (Chrome and FF are pretty easy to develop for)... depends on your use case.
From your comments, I've gathered that you want to capture information from another website that doesn't have Access-Control-Allow-Origin headers that include your domain (e.g. the other site does not have CORS enabled). This is not possible to do cross-domain and client-side due to the Same-Origin Policy implemented in most modern browsers. The Same-Origin Policy prevents any resources on your site from interacting with resources on any other site (unless the other site explicitly shares them with your site using the Access-Control-Allow-Origin HTTP header).
If you want to get information about another site from your site, there is no way around using server-side code. A simple solution would be to implement a server-side proxy that re-serves off-site pages from your own origin, so the Same-Origin Policy will not be violated.
You may get the data using jQuery's load function, and append it to your page.
From there, the DOM nodes from your external page should be accessible for your processing.
$('#where-you-want').load('//example.com body', function() {
console.log($('#where-you-want'))
// process the DOM node under `#where-you-want` here with XPath.
})
You can see this in action here: http://jsfiddle.net/xsvkdugo/
P.S.: this assumes you are working with a CORS-enabled site.

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