How to programatically remove sandbox attribute from an iframe with javascript - javascript

I didn't think this was possible, however, i found this quote:
"It is strongly discouraged to use both allow-scripts and allow-same-origin at the same time, as that allows the embedded document to programmatically remove the sandbox attribute."
My iframe needs to have a sandbox, but only when I am browsing in certain URLs where the embedded browsing context tries to navigate (load) content to the top-level browsing context (Jump out of frame...)
On other pages the sandbox needs to be removed entirely, as it wont allow me to browse away from a site with a different origin...
The frame attempting navigation is sandboxed, and is therefore disallowed from navigating its ancestors.
Programatically changing the sandbox with :
document.getElementById("frame").sandbox = "";
...doesnt work either as this still places restrictions... Therefore, i need to somehow remove the attribute entirely, how would i go about doing this?

These flags only take effect when the nested browsing context of the
iframe is navigated. Removing them, or removing the entire sandbox
attribute, has no effect on an already-loaded page.
More info - Here

You can remove the sandbox attribute from the element using iframe.removeAttribute("sandbox") this will make the iframe non-sandboxed for the next content you load into it, not the currently loaded one.

Related

Is there a way to prevent an iframe from redirecting parent window, but in such a way that "top level" redirects still work inside the iframe itself?

So I've read about the HTML5 sandbox property and I understand that if I want to prevent an iframe redirect its parent window I can use the sandbox property leaving allow-top-navigation out. However when this is done, if the iframe was originally relying on top level redirection, what happens in its place is that it redirects to a blank page, effectively breaking navigation.
Can I prevent the iframe from tinkering its parent window while still allowing "top level" redirects, only letting these work within the context of the iframe instead of being top level?
Edit: For context, I'm working with a third party and its page has a form with a target _top. If the iframe is sandboxed, upon submitting the form users get a blank page, if it's not sandboxed the entire page is redirected. I'm looking for something that would allow to submit the form and show the result within the iframe itself.
With HTML5 the iframe sandbox attribute was added.
At the time of writing this works on Chrome, Safari, Firefox and recent versions of IE and Opera but does pretty much what you want:
Allows the iframe content to be treated as being from the same origin as the containing document
<iframe src="url" sandbox="allow-same-origin"></iframe>
Browser Compatibility
Some Useful links
w3schools for sandbox
developer.mozilla.org iframe
-
You can use the onbeforeunload property and determine if you wan to redirect or not.
Here is the docs page for it
Basically what I would try is this:
Make a function that adds the sandbox attribute with everything, just leaving out the allow-top-navigation, to the iframe
Bind a function to the onbeforeunload property of the iframe that calls the function that adds the sandbox attribute (be sure not to return anything because a dialog will pop-up)
This should work because the request is made in the iframe first, and then we can prevent it from carrying over to our top level window.
Another thing you should check is if you maybe left out the allow-formsoption, which can cause what you are describing.
Please let me know if any of this worked.

Toggling iFrame Sandbox

I'm trying to figure out if it's possible to programmatically change the value of sandbox for an iFrame.
From MDN iframe:
When the embedded document has the same origin as the main page, it is
strongly discouraged to use both allow-scripts and allow-same-origin
at the same time, as that allows the embedded document to
programmatically remove the sandbox attribute. Although it is
accepted, this case is no more secure than not using the sandbox
attribute.
However, changing the attribute in the parent does not successfully trigger sandboxing as that would imply in the child.
document.getElementById('myFrame').setAttribute('sandbox', 'allow-scripts');
The page loaded in that iFrame can successfully gain access to the parent, which would not be the case if sandboxing was working. The attribute does change, but the security is flawed as it does not prevent access to the patent.
console.log(window.parent.document);
The above still works in the iFrame which had the sandbox "programmatically" enabled. This is the case in both Chrome and Firefox, which would imply either intended undocumented functionality or a poorly implemented specification.
Anyone have any ideas on what would be the appropriate expectation?
Please try this fiddle : http://jsfiddle.net/yAwxy/
It's not working when the script is runned onLoad b/c the iframe is already working.
If you try onDomready, the sandboxing is applied b/c the script didn't run yet.
If you log using this fiddle:
<iframe id="myFrame" srcdoc="<script>console.log('Executing script inside iFrame')</script>">
</iframe>
And in the script
console.log('Executing script inside page')
When the script console.log('Executing script inside page') is wrapped onLoad, the outpu is :
Executing script inside iFrame
Executing script inside page
And when wrapped onDomready :
Executing script inside page
Executing script inside iFrame
See also http://jsfiddle.net/yAwxy/1/.
So to change the rules, they must be changed OndomReady
I am running into similar issues when trying to dynamically create iframe contents in Internet Explorer inside of a sandboxed iframe. I tried doing the same thing you did with using javascript to add the sandbox attribute after the iframe was already created and content placed in the iframe (using a javascript: URI in the src= attribute) but the iframe appears to keep it's attributes that were present at the time of being loaded in the page.
Internet Explorer does appear to work differently than FireFox or Chrome when it comes to applying the sandbox attribute. Chrome and FireFox will allow the contents to be dynamically created using src=javascript:function() when the sandbox="allow-scripts" is set. IE appears to apply the unique domain from the sandbox attribute during creation and considers src=javascript:function() to be not-same-origin and will not allow the dynamic creation of the iframe contents.
I am not sure why you are trying to add the sandbox attribute programmatically, but if it is an issue of trying to just load an iframe with dynamic source you can use the srcdoc attribute as well as the sandbox attribute with the only issue being that IE does not support the srcdoc attribute.
To answer your question, I do not believe it is possible to load an iframe and its contents and then add the sandbox attribute after the fact and have the iframe behave as a sandboxed iframe.

How to make javascript that'll click automatically inside iframe's link?

Is it possible ?
I've made on page with iframe, I want a script that'll click automatically inside in one iframe's link.
But I also want that script to detect half link, I mean the link which is in iframe changes everytime, but the first part of the link doesnt change, so the javascript should detect half link which doesnt change and redirect to it...
Why don't you write a "client" library and import it within iFrame. This library listen to a message from HTML5 postMessage call with certain attribute and react appropriately. Since you have access to the parent object through the event object (or window.parent), you can also send response back with the result. This way, it doesn't matter if it's cross-domain and as long as this library exists, you can communicate back-and-forth and even has the iFrame initiate if you write it properly.
I can't share the code with you since it's our proprietary library, but that's part of the idea.
If the content of your iframe is from a different domain, you can't. Allowing this would be a major security concern.
If your iframe content is in the same domain, then you can access the iframe content through its contentWindow property. You can then work with your iframe link the same way you would if the link was in the main page.

How to force a page to stay inside an iframe?

I want to allow any page to be loaded inside an iframe. It's for teaching purposes so I want to know if it's possible to force let's say:
<iframe src="http://www.wolframalpha.com/input/?i=5*sin%28x%29" width="400" height="100">
to stay inside the iframe. By default it has some kind of javascript that opens in full page.
UPDATE: What if i use frames? (please don't throw bricks at me) Could they know if the page is inside a frame?
If the page itself wants to break out of being framed with it's own javascript (which apparently this page is doing), it can do so and I know of no way to prevent it other than turning javascript off in your own browser which obviously isn't an option for general viewing.
On some browsers, you can set an attribute on the iframe element that sets a security policy that prevents the iframe from executing JavaScript. I don't remember the attribute name and not sure which browsers support it (I'm sure ie does, not quite sure about the others). If you have problem finding more details, I'll look it up when I get home (on a mobile right now)
edit: found it - security="restricted". Seems to be IE-only.
If you have links outside of this iFrame and want them to load into that iFrame on the same page, you'll have to give it a name, then target the named iFrame within your link's href.
<iframe src="http://google.com" name="myframe" hieght="100" width="100"></iframe>
<br />
Derp.
However, if you're loading a page into your iFrame that's loading links with target="blank", then those will go to a new window; unless you don't have access to those pages, you won't be able to change the links (short of writing JS to dive into your iFrame, etc).

How do I build an iframe with the same domain as the page in Safari/WebKit

The scene: I'm writing an embeddable widget. It takes the form of a <script> tag, which builds an iframe containing everything it needs to display. The iframe has no src, and the script writes to it with theIframe.contentWindow.document.write(). This keeps the widget contained, and keeps element ids and script from conflicting with the page on which the widget is embedded.
The trick: The widget has to be able to change its size. To do this, it sets its containing iframe's style.height. This requires access to the outer page's DOM. In Firefox and IE, this is allowed, because the iframe's document and the outer document are considered to share an origin.
The twist: In Safari, however, the two documents are considered not to share an origin. The inner document is considered to be at about:blank, while the outer document is clearly using a different protocol and "domain" (if blank can be considered the domain).
The question: How can I build an iframe programmatically whose document Safari/WebKit will consider to have the same origin as the document of the window creating it?
Edit: After further experimentation, I can't find a way to programmatically create an iframe whose location is not about:blank regardless of whether I change its contents.
If I create the frame with document.createElement(), give it a src which points to a real HTML resource on the same origin called "foo.html", and document.body.appendChild() it, Safari's console shows the element as expected in the DOM, but the contents of the page do not appear, and the document is listed in the sidebar as "about:blank".
If I include the HTML for the iframe directly in the page, the contents of foo.html appear, and "foo.html" appears in the sidebar.
If I insert the HTML using document.write(), I get the same result as with document.body.appendChild().
Both programmatic versions work in Firefox.
The best suggestion I could give is to have the iframe set to a blank page on the same server (ie blank.html) and then edit the content. A pain in the rear, I know but it's a workaround.
You could also try
iframe.contentDocument.open("replace");
iframe.contentDocument.write("<b>This is some content</b>");
iframe.contentDocument.close();
However, I'm not sure if that only works in IE. Sorry I couldn't be more helpful than that.
Aha. This seems to be a bug in WebKit. When an iframe is created programmatically, its src attribute is ignored. Instead, the frame defaults to about:blank and must be directed to a URL to point elsewhere. For example:
theIframe.contentWindow.location = theIframe.src

Categories