I am loading HTML content into an iframe using the srcdoc property. The iframe is a sandboxed iframe with no permissions given, so all Javascript in the iframe is blocked. However, remote requests (such as for CSS, images etc.) will still be triggered inside the iframe.
Is there any possible way to tell the iframe to only load what I give it in the srcdoc property and not make any additional requests?
Thanks in advance
The basics
Presumably no because sandboxing the iframe is meant to avoid sharing sensitive data between your main document and your iframe's document or limiting potentially disruptive behavior.
The iframe is still functionally a browser window and will act like such, loading all external resources that are declared in it, with the only difference that it displays within another document rather than another window.
If the code present inside srcdoc has calls to remote resources, then the browser is doing exactly what you are telling it to do by loading them.
If you don't want these resources to be loaded, you will have to edit them out of the srcdoc code.
Actually, a possible solution
That being said, there might exist a way to block the loading of resources by using a Content Security Policy from within the iframe's document using a meta tag:
<meta http-equiv="Content-Security-Policy" content="default-src 'none';">
or
<meta http-equiv="X-Content-Security-Policy" content="default-src 'none';">
I did try this under Firefox 39.0.3 but it didn't work, likely because of the following:
Bug 663570 - Implement Content Security Policy via tag
Regardless, for more information, see:
CSP (Content Security Policy) on the Mozilla Developer Network
Content Security Policy Reference
Related
I'm creating a Chrome Extension which modifies a script served by the server (which I have no control over) to add new functionality to the website, and I had the following idea:
Block the original script via WebRequest, webRequestBlocking.
Send the url of the blocked script to a script injected into the page.
GET this url from the page's script.
Edit a part of the code (string).
Eval the string.
(Another working way is to redirect it to a local modified script return { redirectUrl: chrome.extension.getURL("modified.js") };, inside the Chrome Extension folder, but then it's impossible to modify it on the fly, that's why I want to eval a modified script)
When I try to eval the string in the 5th step, it says: ...'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'nonce-DFX4zDtBDF32343LjE2DFKMs' 'self' https://website.com".
I've tried to use webRequest.onHeadersReceived to see if I could alter CSP headers (as some answers suggested: Edit Content Security Policy in onHeadersReceived), but there is no "content-security-policy" header.
I can see a Content Security Policy meta tag (I've omitted everything except 'script-src'):
<meta http-equiv="Content-Security-Policy" content="script-src 'nonce-DFX4zDtBDF32343LjE2DFKMs' 'self' https://website.com; base-uri 'none';">
From this answer (https://stackoverflow.com/a/27324485/10364842), Chrome Extensions cannot override CSP of Web pages. But someone replies: I know this is incredibly old, but I came across it while trying to inject Artoo.js into a page. The chrome extension does indeed allow you to modify the page you're looking at and let any content through.
Eval works in the content script, but I need to execute the script in the page's context, because it depends on the global scope.
I'm wondering if it's possible to alter CSP of a Web page through a Chrome Extension, or if there is any other way to accomplish this solely via a Chrome extension?
"Extensions have a content security policy applied to them by default. The default policy restricts the sources from which they can load and resources, and disallows potentially unsafe practices such as the use of eval(). See Default content security policy to learn more about the implications of this.
You can use the "content_security_policy" manifest key to loosen or tighten the default policy. This key is specified in just the same way as the Content-Security-Policy HTTP header. See Using Content Security Policy for a general description of CSP syntax." https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_security_policy
I have a frame that looks like this: <iframe srcdoc="*insert HTML here*"></iframe>.
The frame may have some javascript in it and that's okay.
How could I prevent the contents of that frame from connecting to the network?
This includes:
- Javascript's HTTP requests and WebSocket connections etc
- Remote resources referenced in CSS
- External files in the HTML code
Is there some kind of sandbox rule to disable remote connections or do I have to regex all of that out? If so, what should I watch out for when applying the regex?
There is currently no reliable way of accomplishing this.
The sandbox attribute cannot apply the type of restriction you are trying to apply here. A Content-Security-Policy can (with some difficulty), but there is currently no way of reliably applying such a policy to an <iframe> that has its contents set by the srcdoc attribute, as there is no way of simulating HTTP headers for such a document. Indeed, an iframe with srcdoc is simply treated as part of the page which embeds it, and inherits any Content-Security-Policy from that page!
The W3C draft specification "Content Security Policy: Embedded Enforcement" has proposed a csp attribute. In the future, this might be usable to apply restrictions to such a document.
In the meantime, however, you will probably need to serve this content through a sandbox domain, or rethink your design.
I want to load another website on my website using the iframe.
I have seen some other issues while loading using the iframe in some other websites.
So can't we implement iframe to load other domain website pages? If so, do we have another way to load the websites?
The following is the way I tested:
I have tried in
http://www.w3schools.com/tags/tryit.asp?filename=tryhtml_iframe with the following code.
<!DOCTYPE html>
<html>
<body>
<iframe src="https://github.com/mattlewis92/angular-bootstrap-calendar/issues" width="800" height="800">
<p>Your browser does not support iframes.</p>
</iframe>
</body>
</html>
I got the following error.
Refused to display 'https://github.com/mattlewis92/angular-bootstrap-calendar/issues' in a frame because an ancestor violates the following Content Security Policy directive: "frame-ancestors 'none'".
Short answer is NO, you cannot embed this site using iFrame.
If the site allowed it, your code is fine - however in this case you do not have a valid way to embed this site.
The frame-ancestors directive specifies valid parents that may embed a page using the <frame> and <iframe> elements
Obviously they do not WANT you to embed their site:
The look and feel of the Service is copyright © GitHub, Inc. All rights reserved. You may not duplicate, copy, or reuse any portion of the HTML/CSS, Javascript, or visual design elements or concepts without express written permission from GitHub.
HOWEVER
You can use javascript to get the content since their API allows you to do so.
Try ajaxing to https://api.github.com/repos/mattlewis92/angular-bootstrap-calendar/issues - I see Access-Control-Allow-Origin:* so you are able to return that in an Ajax response to your page
$(function() {
$.get("https://api.github.com/repos/mattlewis92/angular-bootstrap-calendar/issues",function(data) {
console.log(data)
$("#result").html(data[0].title);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="result"></div>
or write a proxy on your own server using
curl -i "https://api.github.com/repos/mattlewis92/angular-bootstrap-calendar/issues"
You can put a page from another origin in an iframe if that page allows it. That one doesn't, it uses the Content Security Policy to tell the browser it's not okay via the frame-ancestors policy:
The frame-ancestors directive indicates whether the user agent should allow embedding the resource using a frame, iframe, object, embed or applet element, or equivalent functionality in non-HTML resources. Resources can use this directive to avoid many UI Redressing [UIREDRESS] attacks by avoiding being embedded into potentially hostile contexts.
We recently had a scenario in which an iframe snippet on a server A was pointing to url on server B. There were some malwares being installed by server A on some clients. Can this iframe be the cause. As in hacker injected his url in the iframe's src. What can be the alternatives to iframe etc.
Most likely you experienced XSS
If a hacker is able to change the URL an iframe points to on your site then the iframe is not the problem, your code is.
Any web site could serve up malware, but you have indicated that the hacker has attacked your site and changed the src attribute of the iframe, not the site serving the iframe contents. Even if you replaced an iframe with something else the fact that an attacker has managed to get to the data behind your web site used to generate the page means that they could not limit themselves to iframes, but embed other tactics, such as a redirect, or a hidden link which is clicked by javascript or any other type of common nasty.
Generally IFrame whose content comes from a different domain cannot access the DOM of the parent web site - due to cross domain scripting restrictions. There were lots of bugs involving browsers not implementing such restrictions properly, so an out-of-date client browser might be the cause.
Unless you're running code inside of the iFrame, which you really shouldn't be, it would be a good idea to disable that iFrame from running any code.
Is there a way to remove script from site in frame
from other domain?
No. The some-origin policy means that code in your page can't access the DOM of the page within the frame if it's from another domain.
If the page within the frame is a page that you control (i.e. both domains are yours) you could, I guess, set that page up so that if a certain querystring were added to the URL, the script would be removed on the server-side. But I'm guessing it's not a page you control.
No, but you can use a proxy to load the content from the other domain and re-serve it from your own (with script removed). I presume you're talking about content that you don't control. (Keep in mind that this may or may not be ethical, depending on the content licensing.)
There is in IE:
<iframe security="restricted" />
But it's generally considered a broken security mechanism and you certainly can't rely on it.