问题
I am creating iframes dynamically and I want to prevent scripts that don't originate from the iframes' origin. Is this even possible (via JavaScript/jQuery)? For example, if my page loads an iframe from example.com
with the contents:
<script src="http://example.com/foo.js"></script>
<script src="http://something-else.com/bar.js"></script>
I want the example.com
script to run, but I want the something-else.com
script to be blocked and not run.
I am using NW.js (formerly Node-Webkit), so I have full read-write access to the iframes' contents as if they were same-origin.
I've tried using plugins (like those that bring CORS in the picture, with whitelisting), but nothing I've tried is working.
An ideal solution would also allow me to whitelist specific other origins in addition to the iframe's origin.
EDIT:
Here is my browser project I am trying to implement this in: https://github.com/IdeasNeverCease/Aries
Here is the section of code the iframe loading is done in: https://github.com/IdeasNeverCease/Aries/blob/master/app.nw/resources/scripts/aries.js#L376-L687
回答1:
I want to prevent scripts that don't originate from the iframes' source
This is exactly what a Content Security Policy (CSP) is for. A CSP can specify which origins are permitted for scripts, plugins, styles, media, etc. You need to cause each the iframe to have a CSP that prevents script loads outside of the current origin; this can be done with the simple policy script-src 'self' 'unsafe-inline';
(the unsafe-inline
allows the iframe to have inline scripts and the self
restricts loads to the same-origin resources only)
Traditionally, you need the server to send the Content-Security-Policy
response header when serving the page. However, if you don't have control over the server-sent response headers (but do have control over the page content) you can imitate an HTTP response header with a <meta>
tag like so:
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';">
You can inject this programmatically (but read on for issues):
var m = document.createElement("meta");
m.httpEquiv = "content-security-policy";
m.content = "script-src 'self' 'unsafe-inline';";
iframeElem.contentDocument.documentElement.appendChild(m);
However, this script-based injection might not work for you, because you'll only have a DOM to work with after the DOM is parsed from the HTML source. At that time, and the scripts from any (non-async
) <script>
elements will already have been fetched and run. You may need to manipulate the HTML directly, but I don't know enough about NW.js to tell you the best way to do that.
If you want to disallow all external script resources (even ones from the same origin), you can use script-src 'none' 'unsafe-inline';
. To disallow all scripts, including loaded scripts and inline scripts, use script-src 'none';
In order to whitelist specific origins, simply add them as unquoted items in the CSP:
Content-Security-Policy: script-src 'self' *.twitter.com https://api.facebook.com
A leading *.
allows all subdomains, and a leading https://
limits the whitelist for that domain to secure https://
addresses only.
来源:https://stackoverflow.com/questions/28300192/is-it-possible-to-block-remote-scripts-from-loading-inside-iframe