Checking if a website doesn't permit iframe embed - javascript

I am writing a simple lightbox-like plugin for my app, and I need to embed an iframe that is linked to an arbitrary page. The problem is, many web sites (for example, facebook, nytimes, and even stackoverflow) will check to see if is being embedded within a frame and if so, will refresh the page with itself as the parent page. This is a known issue, and I don't think there's anything that can be done about this. However, I would like the ability to know before hand if a site supports embed or not. If it doesn't, I'd like to open the page in a new tab/window instead of using an iframe.
Is there a trick that allows me to check this in javascript?
Maybe there is a server-side script that can check links to see if they permit an iframe embed?
I am developing a browser extension, so there is an opportunity to do something very creative. My extension is loaded on every page, so I'm thinking there's a way to pass a parameter in the iframe url that can be picked up by the extension if it destroys the iframe. Then I can add the domain to a list of sites that don't support iframe embed. This may work since extensions aren't loaded within iframes. I will work on this, but in the meantime....
Clarification:
I am willing to accept that there's no way to "bust" the "frame buster," i.e. I know that I can't display a page in an iframe that doesn't want to be in one. But I'd like for my app to fail gracefully, which means opening the link in a new window if iframe embed is not supported. Ideally, I'd like to check iframe embed support at runtime (javascript), but I can see a potential server-side solution using a proxy like suggested in the comments above. Hopefully, I can build a database of sites that don't allow iframe embed.

Check x-frame-options header by using following code
$url = "http://stackoverflow.com";
$header = get_headers($url, 1);
echo $header["X-Frame-Options"];
If return value DENY, SAMEORIGIN or ALLOW-FROM then you can't use iframe with that url.

Probably pretty late but what you need to do is make a request, likely from your server and look for the x-frame-options header. If it's there at all you can just open a new tab because if it is there is is one of the following: DENY, SAMEORIGIN, ALLOW-FROM. In any of these cases it's likely that you don't have access to open it in an iframe.

This subject has been discussed forever on the web with a particularly interesting (failed) attempt here:
Frame Buster Buster ... buster code needed
The bottom line is that even if you are able to construct a proxy that parses the contents of the page that you want in your iframe and removes the offending code before it is served to the iframe you may still come under "cease and desist" from the site if they get to hear about you doing it.
If you don't want your development to be widely available, you could probably get away with it. If you want your development to become popular, forget about it, and build a less underhand way of dealing with it.
Or develop it for mobile only... ;)
UPDATE: OK following on from your comment here's a bit of taster:
in javascript capture the click on the link
$("a").click(function(e){
preventDefault(e); // make sure the click doesn't happen
// call a server side script using ajax and pass the URL this.href
// return either a true or false; true = iframe breakout
// set the target attribute of the link to "_blank" for new window (if true)
// set the target attribute of the link to "yourframename" for iframe (if false)
// only now load the page in the new window or iframe
});
server side in PHP
$d = file_get_contents($url); // $url is the url your sent from the browser
// now parse $d to find .top .parent etc... in the <head></head> block
// return true or false

Related

X-frame origins block, is there an alternative to embedding? VUE JS [duplicate]

I am developing a web page that needs to display, in an iframe, a report served by another company's SharePoint server. They are fine with this.
The page we're trying to render in the iframe is giving us X-Frame-Options: SAMEORIGIN which causes the browser (at least IE8) to refuse to render the content in a frame.
First, is this something they can control or is it something SharePoint just does by default? If I ask them to turn this off, could they even do it?
Second, can I do something to tell the browser to ignore this http header and just render the frame?
If the 2nd company is happy for you to access their content in an IFrame then they need to take the restriction off - they can do this fairly easily in the IIS config.
There's nothing you can do to circumvent it and anything that does work should get patched quickly in a security hotfix. You can't tell the browser to just render the frame if the source content header says not allowed in frames. That would make it easier for session hijacking.
If the content is GET only you don't post data back then you could get the page server side and proxy the content without the header, but then any post back should get invalidated.
UPDATE: 2019-12-30
It seem that this tool is no longer working! [Request for update!]
UPDATE 2019-01-06: You can bypass X-Frame-Options in an <iframe> using my X-Frame-Bypass Web Component. It extends the IFrame element by using multiple CORS proxies and it was tested in the latest Firefox and Chrome.
You can use it as follows:
(Optional) Include the Custom Elements with Built-in Extends polyfill for Safari:
<script src="https://unpkg.com/#ungap/custom-elements-builtin"></script>
Include the X-Frame-Bypass JS module:
<script type="module" src="x-frame-bypass.js"></script>
Insert the X-Frame-Bypass Custom Element:
<iframe is="x-frame-bypass" src="https://example.org/"></iframe>
The X-Frame-Options header is a security feature enforced at the browser level.
If you have control over your user base (IT dept for corp app), you could try something like a greasemonkey script (if you can a) deploy greasemonkey across everyone and b) deploy your script in a shared way)...
Alternatively, you can proxy their result. Create an endpoint on your server, and have that endpoint open a connection to the target endpoint, and simply funnel traffic backwards.
Yes Fiddler is an option for me:
Open Fiddler menu > Rules > Customize Rules (this effectively edits CustomRules.js).
Find the function OnBeforeResponse
Add the following lines:
oSession.oResponse.headers.Remove("X-Frame-Options");
oSession.oResponse.headers.Add("Access-Control-Allow-Origin", "*");
Remember to save the script!
As for second question - you can use Fiddler filters to set response X-Frame-Options header manually to something like ALLOW-FROM *. But, of course, this trick will work only for you - other users still won't be able to see iframe content(if they not do the same).

Set Referrer value on a following called url

I have an Html file containing the following code:
<script>
Object.defineProperty(document, "referrer", {get : function(){ return "myreferrer.com"; }});
//document.location="somelink.com";
</script>
From what I've read,maybe the thing I'm trying cannot be done,but I wanted to be sure.
I want to visit the site somelink.com but when my browser finishes the redirection to the location,the document.referrer value to be "myreferrer.com".
If I run the html with this format(document.location in comments)
the command in url --> javascript:alert(document.referrer) is the one I want.
But if I erase the comments and activate the document.location line,the above command will show up an empty document.referrer and not the one I want.
Can I achieve what I have in mind?
Some browser versions allowed you to customize the referer header using the approach of overriding the document.referer property in javascript, but that doesn't appear to be reliable. Even if some browsers still allow that, there's no guarantee it would work in future versions.
If you need a workaround, you could link to the desired referrer domain and serve up an intermediate page that performs the navigation to the final destination URL via an HTML form submission. That should preserve that intermediate page as the referrer.
Within the context of a browser extension however, you can alter the headers via onBeforeSendHeaders

I can't grab data from opened tab

I wrote this code to grab the content of the page which I opened by javascript but my code doesn't work .
could you tell me whats wrong with my code and it would be better if you introduce me a better way to grab a page content, like what I'm trying to do.
var myWindow = window.open("http://www.w3schools.com/jsref/met_win_open.asp", "MsgWindow", "width=200, height=100");
x = myWindow.document.innerHTML;
alert(x);
There are at least two problems there:
You're trying to get the information before it's available (the window.open call returns immediately, before the page is actually loaded).
You can't access information from other origins because of the Same Origin Policy, unless the other site specifically allows you to.
That second issue pretty much makes what you're trying to do impossible to do purely client-side without help from the other site. Instead, you'd have to have a server that requests the information from the other site, and then sends it to your page. (It doesn't necessarily have to be your server; it's possible to use YQL as a cross-domain proxy and there are probably other similar services out there.)

run javascript when opening another page

I'd like to open another web page from javascript (like default navigating, not fullscreen iframe or window.open) and run some javascript code upon loading it.
Steps:
Define a javascript function
Navigate to another page
Browser runs function in new page context
is there any way to achieve this? the only way I remember would be emulating this by loading the page using ajax, and replacing document.body.innerHtml, then running the function, but that would not change location.href, so e.g. the back button or bookmarks wouldn't work. also relative links had to be rewritten at loading, etc...
PS: I know that would be some ugly XSS, but it's needed for example when writing bookmarklets that load a page and fill in a form automatically.
No, you can't do that. That would allow you to do things like steal cookies for session hijacking behind the scenes, so no browsers allow you to do it at all.
While there could be some legitimate use cases, for security reasons you can't do this unless the new page is on the same domain.
What you can do is to write a browser extension if the target browser has extensions support,
Or tell users to open the target page, and use your bookmarklet on that context.
You can do all this stuff if you load the other page from your own server:
Say you want to load http://other.com in your site http://mine.org
You write a tiny serverside script that you can call like this:
http://mine.org/load.php?site1 (with the urls to all the sites you
want to load listed inside load.php or in some database)
but now your site has the security problem: javascript embedded in
http://other.com is run in your sites context.
OK, reserch results:
Impossible methods:
using some persistent function to run on the new page (like I suggested in the question)
using an iframe replacing the whole page (ugly and forbidden by most browsers)
Overkill methods:
write a browser plugin
get the remote page owner to accept some GET argument and do the stuff for you
Remaining method 1, requiring user interaction:
(function(){
if(self.location.href!=targetlocation){
window.alert("Please run this bookmarklet again upon loading the page.");
self.location.href=targetlocation;
}else{
doSomething();
}
return false;
})();
Remaining method 2, doing some nasty proxy stuff:
write some php/etc script to "proxy" the target page
now you can:
use an iframe, because it's not cross-site anymore
rewrite the page server-side before delivering to browser (doing "overkill method: GET argument" by yourself)
Example:
<?php //USAGE: ?uri=http://www.google.com&search[0]=L2dvb2dsZS8K&replace[0]=dGVzdAo=
$page=file_get_contents($_GET["uri"]);
$count = min(count($_GET["search"]),count($_GET["replace"]),100);
for ($i = 0; $i < $count; $i++) {
$page=preg_replace(base64_decode($_GET["search"][$i]),
base64_decode($_GET["replace"][$i]), $page);
}
echo $page;
?>

How can I write something in browser's address bar with JavaScript after the page is completely loaded?

How can I write something ("hello my client" for example) in the browser's address bar with javascript after the page is completely loaded?
Mean writing something in address bar without entering - is it possible?
It seems we can do this job with JavaScript, if not can we do that with server side code?
How?
This is possible, but only the part after the hostname:
history.pushState(null, "page 2", '/foo.html');
Try this in your javascript console, this effectively changes the current path with /foo.html. (It's a new html5 feature, and is available in recent browsers only.)
See mozilla docs: https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history#Adding_and_modifying_history_entries
Browser Compatibility
Why?
This is used to make ajax sites history/bookmark/link friendly by updating the URL as the content is updated. Currently most sites do this by only changing the hash part of the URL (e.g. Twitter with their #!.)
For instance Github uses this for their code browser: https://github.com/blog/760-the-tree-slider
Maybe its already answered # Change the URL in the browser without loading the new page using JavaScript .
You can set location.hash, but you can't replace the entire URI.
The reason this is not possible is it presents a security violation. This is why phishers write a gif file over where they believe the address bar will be.
My question is why would you want to do this? The only reason I can think of is you want to make someone think they are at http://Iamreallyyourbank.com when they are at http://IamStealingYourMoney.com, which is why the security is in place.
This is not possible. You cannot change the URL displayed in the browser. Not only would it be a horrible security practice, it would be a violation of trust to the people visiting your site.

Categories

Resources