I am basically trying to prevent any custom dialog boxes to be shown in my webpage.
Basically third party ad-networks, which at times may use some malicious code to show alert() to the end user.
I've come across a simple way, to override the alert on the main page:
Window.prototype.alert = function() {console.log("alert prevented!")}
So for a basic html page like this, it works just fine:
<html>
<body>
<script>
Window.prototype.alert = function() {console.log("an alert was averted");}
</script>
<div>
<a onclick="alert(1)"> This is an alert inside the body</a>
</div>
</body>
</html>
But introduce an iframe in the picture, and the alert within the iframe would pop-up.
What I still want to achieve is, if there is an <iframe> or anything similar HTML component, which basically would create a separate window, should also not be allowed to display any alert().
I'm not quite sure if this is possible, but still any suggestions?
It is probably not possible for old browsers, but newer browsers honor the sandbox attribute in iframe. “Newer” means IE 10 or newer or any reasonable new version of Chrome or Firefox. See support details.
For example, if you wish to disallow popups only, use this:
<iframe src=foo.html sandbox=
"allow-forms allow-pointer-lock allow-same-origin
allow-scripts allow-top-navigation."></iframe>
Here I have listed all the possible values that this attribute value may contain except allow-popups, so that’s the only feature that will be disabled by the attribute.
Related
Setting src directly in iframe is working as expected
I'm trying to embed a Sharepoint document here.
For eg
<iframe src="https://rocketlane123-my.sharepoint.com/personal/lokeshkannan_rocketlane123_onmicrosoft_com/_layouts/15/Doc.aspx?sourcedoc={8822527b-0c56-44f9-8263-40c737db903c}&action=embedview"
width="476px"
height="288px" />
Whereas when I set the src in the script it's failing
<iframe id="x" width="476px" height="288px"></iframe>
<script>
document.getElementById('x').src = "https://rocketlane123-my.sharepoint.com/personal/lokeshkannan_rocketlane123_onmicrosoft_com/_layouts/15/Doc.aspx?sourcedoc={8822527b-0c56-44f9-8263-40c737db903c}&action=embedview";
</script>
This happens explicitly with SharePoint. So I would like to understand a couple of things here.
1. Am I doing something wrong?
2. Is there any CSP headers which block the parent from adding via JS?
3. Is there any official way from SharePoint to allow this?
3. Is there any way to hack this?
Thanks in advance.
Since this happens across chrome, safari and firefox I think it's not a bug in a specific browser.
Trying this in Firefox yields this error message:
To protect your security, login.microsoftonline.com will not allow
Firefox to display the page if another site has embedded it. To see
this page, you need to open it in a new window.
Opening the console gives this message:
The loading of [url] in a frame is denied by “X-Frame-Options“
directive set to “DENY“.
This is a header that's set by login.microsoft.com to disable embedding the link as an iframe.
This link details this design choice: https://learn.microsoft.com/en-us/sharepoint/troubleshoot/sites/cannot-display-sharepoint-pages-in-iframe
The link mentions you can override the behavior by setting 'AllowFraming', though it doesn't recommend it, as there may be site-breaking changes by embedding it.
A guide to use this feature can be found at this link
The problem is in, javascript amp; should not represent as &.
Change your link to
<body>
<iframe id="x" width="476px" height="288px"></iframe>
<script>
document.getElementById('x').src = "https://rocketlane123.sharepoint.com/sites/MyDocsforSP/_layouts/15/Doc.aspx?sourcedoc={6d327004-5d52-4e42-9707-c964631f8e65}&action=embedview";
</script>
</body>
I'm making a chrome extension that loads an <iframe> of another site onto the New Tab page. Right now I'm loading YouTube's subscription page (don't worry about the Same-Origin issue, I solved that already), but now I'm trying to cut everything out of the page except the #content element (the subscription feed element).
Here's my code:
Background.html
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="script.js"></script>
</head>
<iframe id="left" src="left.html" name="left"></iframe>
<iframe id="right" src="right.html" name="right"></iframe>
</html>
Left and Right .html
<!DOCTYPE html>
<html>
<body>
<input type="button" value="Load new document" id="loader">
</body>
<script type="text/javascript" src="window.js"></script>
</html>
Window.js
document.addEventListener('DOMContentLoaded', function() {
document.getElementById("loader").addEventListener("click", loadUrl);
});
function loadUrl()
{
window.location = 'https://www.youtube.com/feed/subscriptions';
[].forEach.call(document.querySelectorAll(!'#content'),function(e){
e.parentNode.removeChild(e);
});
return false;
}
As you can see, right now I'm loading it in with a button. Once it's pressed, it loads YouTube and should cut out all the html except #content, but it's not. Is there another way to solve this, possibly with jQuery? Thanks!
document.querySelectorAll(!'#content')
won't meet your requirements, you should use the following instead if you do want to remove all elements except #content.
document.querySelectorAll('*:not(#content)')
#content isn't accessible to document, because the global document is on a different page - the page containing the iframes, but not their contents. Moreover, document.querySelectorAll(!'#content') is not a valid selector string - that will be interpreted as document.querySelectorAll(false) because ! of a non-empty string returns false.
You're going to have a hard time getting access to the contents of an iframe, just in general. Most browsers, like Chrome, won't event load the contents of an iframe if X-Frame-Options is set to SAMEORIGIN, which, for youtube, it certainly is.
Supposing you're getting around this (with a reverse proxy, perhaps?), you can get the contents of an iframe using JavaScript like so:
iframe.contentWindow.document
You can then use querySelector and friends on the iframe:
iframeDocument.querySelector('#content')
And if you want to cut out a node, you should remove() it:
iframeDocument.querySelector('#content').remove()
Now, having said all of that:
Don't do this.
You're abusing iframes, which requires some very creative (read: brittle, hacky) code, and Youtube certainly has a public API from which you can get access to someone's Youtube feed - and in a way that Youtube is far less likely to block by tightening security, or even by accident. (Suppose the HTML on their page changes, so #content contains everything. Or suppose they decide to check that the correct origin is requesting the page with JavaScript, and block you.)
What you want, you should use Youtube's API for.
I've asked this question before this one, trying to figure out why I was seeing scrollbars on the a-ads iframes, on this website, while some swear they didn't see them!
Hence, I have discovered that the appearance of the iFrame scrollbars is by execution order. And with faster or slower computers, results may vary.
I realize that I have to replace scrolling="no", a strong (but unsupported in HTML5), attribute that forces no scrollbars on iframes, with a JavaScript, or CSS alternative. However, the CSS overflow:hidden; is too weak to override whatever style the iframe's source may contain (e.g. overflow:scroll, overflow:auto, etc.). So the solution must be with JavaScript.
The caveat however, is that the javascript must activate after the iframe itself is loaded, but before the source (src="") is loaded. Because if scrolling="no" is replaced after the source is loaded it has no effect on the outcome of the iframe display. Though, if it is place before the <iframe> tag markup is reached, how does the JavaScript know what to modify? It is as good as not present at that point.
One More Problem: The source can't be stripped from the <iframe> tag, and replaced in JavaScript. We've tried that, and while it worked....sort of... we lost ad impressions and clicks into a black hole, because the spider (i.e. bot) at a-ads couldn't, or had problems with, detecting the proper a-ads code on the webpage. But if we left it in the iframe and just reloaded the source after scrolling="no" was set, then that would result in double ad-loads (i.e. invalid impressions).
This is a real pickle!
All the Einsteins of the world - You're Needed!
Also, this S.O. question doesn't apply.
Screenshots
Chrome Proof
IE Proof
Opera Proof
Firefox was best-behaved
This issue has now been solved, for now, I think. Here is the solution:
<head>
<script type="text/javascript">
function noScrollBarsOnAAdUnit( ElementID )
{
document.getElementById( ElementID ).setAttribute("scrolling", "no");
return true;
};
</script>
</head>
<body>
<script type="text/javascript">noScrollBarsOnAAdUnit( 'aa-unit-top-center' );</script>
<iframe id='aa-unit-top-center' style='width:468px;height:60px;' class='a-ads-frame' data-aa='[ad-id]' src='https://ad.a-ads.com/[ad-id]?size=468x60'>
<!-- iframe fallback message here -->
</iframe>
<script type="text/javascript">noScrollBarsOnAAdUnit( 'aa-unit-top-center' );</script>
</body>
Fellow S.O. members, please, check this page, to assure this fix is consistent, and really works at least 99.99%, if not 100%, of the time.
Thanks!
-James A.
I have a main page that loads a default link in an iframe http://mypage.com/myurl. Having it in a blog, I want to dynamically change that default link inside the iframe, for every post page. I load the default link like that:
<iframe width='1000' height='500' name='iframename' frameborder='0'
src='http:/mypage.com/myurl'></iframe>
(works on all browsers) and i change dynamically the link inside the iframe by putting this code in every post page:
<script type="text/javascript">
document.iframename.location = "http://mypage.com/mynewurl";
</script>
It works fine on chrome and ie, but it does not work on firefox!!
Any ideas or work around?
Here a simplified example www.tinyurl.com/9l7zt2n see the difference with firefox it loads the default link in the iframe. ie and chrome can change with the added javascript.
If it helps to test it on the blog www.tinyurl.com/9axhquh u can see it working on chrome and ie, if u click on any post title or "read more" to load the post's page, the iframe on top changes accordingly
Any ideas or work around?
document.iframename.location is probably not supported crossbrowser.
try:
<iframe width='1000' height='500' id='iframeid' frameborder='0' src='http:/mypage.com/myurl'></iframe>
<script type="text/javascript">
document.getElementById('iframeid').src = "http://mypage.com/mynewurl";
</script>
this means:
accessing an element by name through a document.elementName syntax is not supported.
an iframe element has no property called location. location is a property of window. You can access the window of an iframe by using using contentWindow.
I've written a short test here http://jsfiddle.net/FyNW9/. Run it in different browsers.
I would like to create an <iframe> on the page, but then add the src later. If I make an iframe without an src attribute, then it loads the current page in some browsers. What is the correct value to set for the src so that it just loads a blank iframe?
The answers I've seen are:
about:blank
javascript:false
javascript:void(0)
javascript:"";
url to a blank page
Is there a clear winner? If not, what are the tradeoffs?
I'd like to not have mixed content warnings for HTTPS urls, nor any back-button, history, or reload weirdness in all browsers from IE6 onward.
Not sure if all browsers support "about:blank", so I'd just go with your own blank page then.
Another idea: Why not add the whole iframe using javascript instead of just the src?
Standard approach when creating an "empty" iframe (as an iframe shim, for example), is to set the src as javascript:false;. This is the method used by most of the JavaScript libraries that create iframe shims for you (e.g. YUI's Overlay).
What about
about:blank
Re your comment clarifying that you're planning to use the iframe as the target for a form submission:
I would use an empty document on the server that sends back a 204 no content.
It avoids
"mixed content" warnings in IE and HTTPS mode
Unnecessary errors because a client doesn't understand the javascript: protocol
and other exotic shenanigans.
It's also valid HTML.
So what if it generates an extra request? Set the caching headers right, and there will be only one request for each client.
javascript:false:
IE10 and FF (checked in v23 in Linux) will show 'false' as content.
javascript:void(0) && javascript:;:
IE will show 'cannot display the webpage' error in the iframe. Also, when setting the src from a valid url to javascript:void(0), the page will not get blank.
about:blank:
Works in all browsers but IE 9 sends an request to the server with path "null". Still the best bet IMO
Checkout http://jsfiddle.net/eybDj/1
Checkout http://jsfiddle.net/sv_in/gRU3V/ to see how iframe src changes on dynamic updation with JS
javascript:false works in modern browsers.
What I've seen is that this only "fails" when dumb spiders try to load javascript:false as a page.
Solution: Block the dumb spiders.
As I posted in this question: Is an empty iframe src valid?, it looks acceptable to just leave out the src= attribute completely.
IMO: if you don't put the src, your page won't validate. But's about it.
If you put a src="", your server will log many 404 errors.
Nothing is really wrong as in "damaging". But then, is it actually not wrong to use an iframe in itself?
°-
Yes, I know I'm reviving an old thread. Sue me. I'm interested in the answer.
I don't understand why having the trigger being a form submit precludes dynamically creating the IFrame. Does this not do exactly what you want?
<html>
<head>
<script type="text/javascript">
function setIFrame(elemName, target, width, height) {
document.getElementById(elemName).innerHTML="<iframe width="+width+" height="+height+" src='"+target+"'></iframe>";
}
</script>
</head>
<body>
<div id="iframe" style="width:400px; height:200px"></div>
<form onSubmit="setIFrame('iframe', 'http://www.google.com', 400, 200); return false;">
<input type="submit" value="Set IFrame"/>
</form>
</body>
</html>
I run into this line of code:
iframe.setAttribute("src", "javascript:false");
as well. I wanted to remove javascript:URL.
Found this note from the Web Hypertext Application Technology Working Group [Updated 2 October 2019]
[https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-iframe-element][4.8.5_The_iframe_element]
The otherwise steps for iframe or frame elements are as follows:
If the element has no src attribute specified, or its value is the
empty string, let url be the URL "about:blank".