I'd like to show the content of both a txt and a pdf file and embed these into a webpage.
The files are located on a webserver with a different domain.
How can I include those? Is the only change using an iframe? Or could I also use the embed or different tags? If yes, how?
<iframe ng-src="{{some.url.text.or.pdf}}"></iframe>
There are several issues you may encounter:
Angular will deny you setting ng-src out of your domain by default. To overcome this use $sce.trustAsResourceUrl as described here - How to embed an external file in a webpage with angularjs?
Any external url you refer, may still deny embedding it by having X-Frame-Options: SAMEORIGIN set in the response headers and you can't do anything about it. The browser will deny embedding if such headers are present.
Not every document type can be embedded and the support depends heavily of the browser and it's plugins.
When it comes to embedding anything in iframe, the problem is that you cannot get the size of the content if it's not from the same origin. Making it impossible to calculate proper iframe size. Thus usually ending up in bad user experience. So before embedding any document, consider if user is better off having it as a download or in a separate window.
For a PDF specific solution without iframe/embed check out this post - Recommended way to embed PDF in HTML?
not complete but something like
<iframe iframe-set-dimentions-onload width="90%" my-frame="fullyLoaded()" ng-attr-srcdoc="{{htmlResponse}}" id="iFrame">
.directive('iframeSetDimentionsOnload', [function(){
return {
restrict: 'A',
link: function(scope, element, attrs){
element.on('load', function(){
if(window.localStorage.getItem("iFrameHeight")==="present")
iFrameHeight = element[0].contentWindow.document.body.scrollHeight+125 + 'px';
else
iFrameHeight= element[0].contentWindow.document.body.scrollHeight+'px';
element.css('height', iFrameHeight);
});
}
}}])
do whatever u want after loading at $scope.fullyLoaded()
The files are located on a webserver with a different domain
If it's a cors issue , then it's a different case
Related
I am planning to create an open source education web app where people can add and edit the content (a bit like Wikipedia).
However I wish to add another feature that allows the user to add their own interactive content using JavaScript. (similar how JSFiddle does it)
What are the security concerns in doing this?
Optional question: How can these issues be overcome?
Yes you could use HTML5 Sandbox to only load user scripts in an IFrame.
You should only host user content from a different domain than your main site. This will prevent any XSS attack if an attacker convinces a user to visit the page directly (outside of the sandbox). e.g. if your site is www.example.com you could use the following code to display the sandboxed IFrame (note .org rather than .com, which is an entirely different domain):
<iframe src="https://www.example.org/show_user_script.aspx?id=123" sandbox="allow-scripts"></iframe>
This will allow scripts, but forms and navigation outside of the IFrame will be prevented. Note that this approach could still risk a user hosting a phishing form to capture credentials. You should make sure that the boundaries between your site and the user content are clear within the user interface. Even though we haven't specified allow-forms, this only prevents a form from being submitted directly, it does not prevent form elements and JavaScript event handlers from sending any data to an external domain.
The HTML5 Security Cheat Sheet guidance on OWASP states this is the purpose of the sandbox:
Use the sandbox attribute of an iframe for untrusted content
You should test whether sandbox is supported first, before rendering the IFrame:
<iframe src="/blank.htm" sandbox="allow-scripts" id="foo"></iframe>
var sandboxSupported = "sandbox" in document.createElement("iframe");
if (sandboxSupported) {
document.getElementById('foo').setAttribute('src', 'https://www.example.org/show_user_script.aspx?id=123');
}
else
{
// Not safe to display IFrame
}
It is safer to do it this way by dynamically changing the src rather than redirecting away if sandboxSupported is false because then the iframe will not accidentally be rendered if the redirect doesn't happen in time.
As a simpler alternative, without the need to check whether the sandbox is supported, you can use the srcdoc IFrame attribute to generate the sandboxed content, making sure that all content is HTML encoded:
e.g.
<html><head></head><body>This could be unsafe</body></html>
would be rendered as
<iframe srcdoc="<html><head></head><body>This could be unsafe</body></html>" sandbox="allow-scripts"></iframe>
Or you could construct a data blob object, being careful to HTML encode again:
<body data-userdoc="<html><head></head><body>This could be unsafe</body></html>">
<script>
var unsafeDoc = new Blob([document.body.dataset.userdoc], {type: 'text/html'});
var iframe = document.createElement('iframe');
iframe.src = window.URL.createObjectURL(unsafeDoc);
iframe.sandbox = 'allow-scripts';
</script>
Of course you could also set the unsafeDoc variable from a JSON data source. It is not recommended to load an HTML file, as this has the same problem of it having to be from an external domain, as the attacker could just entice the user to load that directly.
Also, please don't be tempted to write user content into a script block directly. As shown above, data attributes is the safe way to do this, as long as correct HTML encoding is carried out on the user data as it is output server-side.
In these cases you can leave src as blank.html as older browsers that do not support srcdoc will simply load that URL.
As #Snowburnt touches upon, there is nothing stopping a user script from redirecting a user to a site where a drive-by download occurs, but this approach, assuming a user is up to date on patches, and there are no zero day vulnerabilities, this is a safe approach because it protects its end users and their data on your site via the same origin policy.
One big issue is cross-site scripting where users add code that tells the browser to open and run code from other sites. Say they add something that creates an iFrame or a hidden iFrame pointing to a site and starts downloading malicious code.
There's no simple way around it (thanks to Bergi in the comments) to make sure no elements are created and no ajax calls are made.
I've been a member of sites that provided this functionality, but for those sites I paid for my own space so any vulnerabilities I add are inconveniencing my own clients, in that case it's a little more okay to let that slip by since it's not a security leak for everyone.
One way around this is to create customizable controls for the users to use to add interactivity. The plus is that you control the javascript being added, the minus is that your user base will have to request and then wait for you to create them.
I have a file
file:///C:/Users/7%20Legged%20Spider/Desktop/test.html
When I set it into an iframe
< iframe src="file:///C:/Users/7%20Legged%20Spider/Desktop/test.html">
The iframe is blank, why is this and how can I fix it
It is because of security issue. You can not bypass it by any mean.
You should not use local file as href because of:
Security problems
"Unexpected" URLs (not everyone has C:\)
If you are using it only for development, you may want to upload the file to your server in order to include it.
I use some iframes in my page and I'd like to access iframe elements from parent page and the opposite.
From the parent page I add Iframes with:
<iframe id="iframe1" src="./iframe1.html" width="100%" height="100%"></iframe>
and I try di access iframe element by javascript with:
window.frames['iframe1']
...
From iframes I use something like
//to get elements
var obj = parent.document.getElementById('iframe1');
//to call methods
parent.document.mymethod();
In both situation it give me the following error:
Unsafe JavaScript attempt to access frame with URL file:///C:/Users/marco/test/iframe1.html from frame with URL file:///C:/Users/marco/test/index.html. Domains, protocols and ports must match.
I know that file have to be in the same domain. The problem is that I don't call files from web server, but browser has to read files directly from resource path. This because I will put theese files embedded in an Android app and I will read them with a webview from local resources.
I tried to set manually window.domain = 'mydomain' but nothing changed and also to use absolute path for iframes.
I use Sencha Touch, if it can be usefull.
Any ideas?
Thanks for your time,
Marco
Lets assume I have my browser load an Iframe with <iframe src="test.html">
Can I, using ajax, load the content of test.html into a div in the main html page?
This idea is my solution for that fact that I'm actually trying to overcome the limitation with making ajax submits to remote hosts. The plan is to generate the dynamic page with 0 sized iframe which makes report request to remote host. Then, after the page (& iframe content) loads I will copy the iframe content into a div using JS.
Tips are appreciated,
Thank you,
Maxim.
No, you can't.
When you load a page from a different domain into the iframe, it becomes unreachable. You can no longer access the contents of the iframe, as it comes from a different domain.
The only thing that I know of that you can reliably load from a different domain is a script, which JSONP uses.
Can I, using ajax, load the content of test.html into a div in the main html page?
Yes (since your example has a relative URI and is on the same host) …
This idea is my solution for that fact that I'm actually trying to overcome the limitation with making ajax submits to remote hosts.
… and no. You still can't read data from remote hosts.
I'm sure someone will correct me if I'm wrong, but I believe that scripting across domain boundaries is restricted. Have you tried it? Here's a function that may help out.
function insertDivFromFrame(divname, framename) {
var frame = document.getElementById(framename);
var d = frame.contentWindow || frame.contentDocument;
if (oDoc.document) {d = d.document;}
document.getElementById('yourdiv').innerHTML = d.body.innerHTML;
}
I'm not sure this code works... see http://xkr.us/articles/dom/iframe-document/ for more help on this.
... you may, however, design an AJAX request to local host and retrieve information from the remote server (as described here).
If you write a php/perl/etc. script to output the contents of a document from another domain, it'll give you access to the contents as the resulting page would be considered by javascript to belong to your domain. If you're not familiar with any server-side scripting languages, I'm sure you'd be able to find a script that'll do this for you by doing a simple google search.
Best of luck.
I have a window, with an iframe in it.
When i clicking a button, then the iframe will load (loaded from a web site).
Is it possible to retrieve the content of that iframe? How can I retrieve the content of that page?
I can view the source code by left clicking iframes View Source.
I need to store the source in a DB.
1.
var iframe = document.getElementById("ifrm");
alert(iframe.contentWindow.document.body.innerHTML );
2.alert(window.frames['ifrm'].document.body.innerHTML);
these two comments are showing "access denied" error.
Please help me.
This should work (if it's on the same domain):
document.getElementById('iframeId').contentWindow.document.body.innerHTML
Note that you need to make sure the frame has been loaded completely before you run this code. Otherwise, you will get strange exceptions.
Disclaimer: I have not tested this.
Here's the google query I used: google query
It is generally not possible to read the contents of an iframe loaded from another server, due to the same origin security policy. However, it looks like you want to store the content on the server anyway, so why not request the content from the server?