How should I resolve this conflict between facebook iframes and browser security? - php

I have a facebook application that I built as an FBML app. Recently I noticed that FBML is deprecated and that Facebook now recommends only iframe apps. Something I initially avoided because my understanding is that iframes are not valid xhtml code, and at the time I was trying to write 100% validated code for everything.
However I also don't like building unsupported applications, so I set about changing my app to use fully rendered html pages using the iframe method of display.
My pages render perfectly on their own when I display them in their own window however they are completely blank in Safari when rendered inside a frame provided by Facebook. At first I was stumped and couldn't figure out why nothing rendered, until a friend using Internet Explorer told me he was seeing the following error:
To help protect the security of information you enter into this website, the publisher of this content does not allow it to be displayed in a frame.
So I started googling this error, and found mountains of forum discussions between confused people trying to get their frame code working and figured out it was an error that appeared overnight back in 2009 when IE8 was introduced. A little more digging on the Microsoft site reavealed that it is a security feature invented by Microsoft to prevent click-jacking.
The apparent cause of this is the server sending an X-Frame-Options heading, and the response of Firefox and Internet Explorer is to display an error message about security and frames, while the response of Webkit browsers such as Chrome and Safari is to render an unhelpful blank frame. I own the hardware running the apache server and I wrote all the html, and I certainly never explicitly sent the X-Frame-Options header, so I must assume that my installation of php sends this header by default on all pages that it serves up as a blanket security enhancement (either that or Apache is doing it).
Obviously, now that I know what causes it, I could figure out who is sending the header and stop it, but my question is on of best practises: Click-jacking prevention is obviously a worthy cause, and since some part of my server chain deems it important enough to send this header without asking, clearly someone thinks it is a good idea. However, Facebook apps, by design, load content from another website within an iframe, so I'm surprised there is little or no talk that I can find about this on the internet. Is there another way around this, or is it simply a case of something that should not be turned on for a page that is intended to be viewed from within an iframe?
Furthermore, if getting rid of the header is the correct approach, does anyone know why it is getting sent and where to turn it off? I'm running on a Snow Leopard Server with the default installation of apache and php.

Search the Apache config files for the option
$sudo grep -ir 'x-frame-options' /etc/apache2
Credit

Related

Google OAuth for websites in embedded browsers

Google no longer allowing embedded webviews as it is a disallowed_useragent for OAuth sign in. For most situations, this is completely fine and there is a workaround. However, I have run into a situation where this prevents websites from being able to use a web-server OAuth implementation.
The Issue:
Nginx PHP server running the Google PHP SDK, using their O-Auth implementation. This works fine on everything except embed browsers. Typically this is okay, however, if a user tries to sign up to our website in an app which uses an embedded browser, we get the disallowed_useragent error (See picture at bottom). This doesn't appear to be a problem in Android Facebook Messenger but can be replicated on the iPhone 7 Plus Facebook Messenger.
Current Research:
I tried to look for explicit workarounds. E.g. ways to force the link to open in the primary phone browser (e.g. Safari app) but all implementations point to app side fixes, which can't be done from a website.
Question:
How can I implement Google Oauth when some users may be using these embedded browsers, without making the user to take an extra manual action (e.g. Open in Safari/Chrome)?
This question is very opinion based but I will give you my opinion.
How should I implement Google Oauth when some users may be using these embedded browsers, without making the user to take an extra action?
You cant really. If someone is using an embedded browser in Facebook messenger (embedded browser) to open your auth link its not going to work. To my knowledge there is no way to force or over ride Facebook messenger or any other app that uses its own embedded browser. Again this is just my opinion but there are a lot of apps out which have started forcing their users to use these embedded browser's. One could question how secure they are and that it is better to use the real installed browser. Do you think this is why google has enabled this to begin with?
I would like to avoid going down the road of detecting the user-agent web-side and force the user to open the link in Safari.
I don't know that sounds like a pretty decent solution to me. It may feel a like over kill a little but if it works go with it.
There's another scenario that is causing issues.
If you have a web app - not a native app with an embedded browser - the user can always choose to put the shortcut to the HomeScreen in iOS.
But when they go to that HomeScreen shortcut to run the app, it will strip "Safari/6xx.x" from the user agent string.
Now, Google sees this as an "Embedded Browser" and denies access to OAuth.
So - "No Web-App-Capable" for you!
If you turn off this meta tag:
<meta name="apple-mobile-web-app-capable" content="yes"/>
two things happen in iOS:
The website now opens in the Safari browser window instead of the cleaner Web-App method.
The website uses the complete Safari useragent which will allow OAuth to work.
The real shame here is that the decisions of Google (To deny non-standard browsers to access OAuth) and Apple (To remove the Safari version in the user agent for homescreen shortcuts) have backed us into the corner where any site that could look really nice in web-app mode can't utilize this OAuth from google.
I've been trying to find a way to spoof the user agent to add the safari version into it so that everything works in homescreen web-apps, but I don't think I can make it work. It seems that safari doesn't allow you to change the navigator.userAgent and on top of that, I'm not sure how it would handle new popup windows in WebApp mode.

Embedding HTTP content into HTTPS site

We have a unified portal which links multiple services through a jQuery tab based interface making use of iframes to display content from different services. Our portal runs on a secure server with HTTPS/SSL. While most of our external services are HTTPS, two of them aren't. Obviously we are aware of the issues with mixed content and we didn't like the idea of having non-https sites within the portal, but we didn't have a choice. Everything was ok until a few days ago when Google updated chrome to version 30, which now silently blocks mixed content.This has created a great number of problems for us. We contacted the external services and asked them if they could upgrade their services to HTTPS and one of them has come back saying they have no plans to do so for the next 2 years.
Obviously this is a problem. We tried getting around the problem by getting this service to open into a new browser window, but this is a rather inelegant workaround which I would like to get rid of, if at all possible. Is there any way that I can use AJAX or PHP to prefetch the page in question and then display it within the portal iframe without Chrome blocking it?
I would be very grateful for any advice at all. I do understand how bad an idea it is to mix secure content with non secure content, but I have no choice in the matter as my manager is adamant that the service have to be a part of the portal.
Thanks in advance.
Regards
Alex
A somewhat simple solution would be to use a reverse proxy. You can configure Apache quite easily to take an HTTPS connection, fetch the requested content from another URL and return it. See mod_proxy. The problem is that the browser will necessarily see a different URL/domain on its part (your reverse proxy), which may or may not cause problems with cookies or hardcoded links.

For security reasons, framing is not allowed

Trying to set up my first FB app, I tried using different PHP example codes, but for some reason when I try to access the app, I always get a Java window saying For security reasons, framing is not allowed. I have SSL on my server, and another FB app on my server that's not using FB SDK is working fine. Anyone has any ideas?
You will get that same error on StackOverflow if you try to open it in a frame as well. This is due to security concerns as it is the first step towards clickjacking a site. See this Coding Horror blog post for a full explanation.
TL;DR; Don't frame external sites...including FB which is in a different space than your server.

Is there a way to force open a new browser window from MOzilla to IE by Onclick function?

Iam getting new window pop up by using window.open(), but need When i click button in Mozilla browser, a new pop window should open in Internet Explorer, Is it possible......
What about non-Microsoft operating systems? Internet Explorer is not available on e.g. Linux. As such this is not possible. Executing arbitrary external applications should not be possible, at least not without the user's explicit permission. That would be a serious security risk.
Why do you want to do this? Does you website not render properly on anything other than IE? If that is so, then you may want to improve the HTML/CSS/Javascript to make it more standards/cross-browser compliant.
Of course, you could just ask or advice the user to view your website in IE. Not a fancy solution, but it has been done that way for ages. Firefox has the IE Tab add-on, which allows users to render pages using IE's render engine inside the Firefox GUI. This makes things slightly more convenient, but it's still a manual process which requires the user's explicit consent.
As a side note, something akin to what you want is possible with the combination IE/Google Chrome Frame. If you add the following meta tag in the target page, then IE with Google Chrome Frame installed will use Google's instead of IE's rendering engine (source):
<meta http-equiv="X-UA-Compatible" content="chrome=1">
I am not aware of any other browser/plugin combination with this feature.
No. Not possible.
If it was possible to run other applications straight from the web, you would already have tons of malware on your computer. Of course this is impossible and not everyone has Windows.
It might be possible if you have control over clients PC (like e.g. company network). There are handlers for special urls in Firefox that allow you to open external application. It requires approval from user. I saw such links for Skype or other IM clients. And one another example is mailto: link.
Well, there are no such compatibilities in DOM, niether there's access necessary for JS to know system capabilities... but I just found this add-on, IE View, that let's you load pages in IE with a right click (using context menu) and mark certain sites to be loaded from IE only.

How do you ask an external program to open a file being served through a web browser? What about detecting if the external program is installed?

I have a two part question. The first I think I have an okay answer to....
I am looking to force an external program to be called up to view a configuration file for an application my company is working on. The basic gist I guess is to set the Content-type header to type that your application is associating with, and then serving the contents of the file. I was thinking its simply structured like this:
<?php
Header( "Content-type: application/blahtype" );
?>
output of xml configuration file goes here...
Any other best practices here? Obviously the user is going to have to allow the external application access to this file universally in all browsers, unless they have a plugin installed in their browser that will handle the content-type, like adobe pdf. This isn't viable for our company right now, so we're willing to live with the confirmation screen.
The second part of the question is a little bit more complex, I think. How do we detect if the user has the application installed, and if they do not, serve them different content (a sign up page, or the application executable itself)? I'm not wondering about the logistics of serving different content, but simply the detection process. Is it possible for an application to install a lifetime cookie in the browsers cache installed on the machine? That's not a perfect solution, because the user could clear their cache of course. How else can we accomplish this?
Examples of programs that do this are Amazon MP3 Downloader (I've actually gotten into a bad state with this once or twice), and iTunes U. You can see iTunes U example on Stanfords CS193P page here: http://www.stanford.edu/class/cs193p/cgi-bin/index.php
Much appreciate any advice,
Josh
For part 1 of your question, as long as your application is correctly registered to handle that MIME type, then, yes, the browser should [prompt the user and launch your application](http://msdn.microsoft.com/en-us/library/ms775148(VS.85).aspx "MSDN: Handling MIME Types in Internet Explorer").
An alternative approach would be a [protocol handler](http://msdn.microsoft.com/en-us/library/aa767914(VS.85).aspx "MSDN: Registering an Application to a URL Protocol"). Instead of registering a MIME type for your application, you register a “protocol” that goes in a URL, in place of the http://. If your protocol is called myapp, then you could create links like this:
Link
While you can only pass a small amount of information this way, you could pass a GUID or tag that the application, once launched, can use to retrieve the full document from your server.
Edit: For part 2 of your question, iTunes uses a plug-in. Looking at the code that’s used to redirect to iTunes, you’ll see something like this:
<Object id="iTunesDetector" height="1" classID="CLSID:D719897A-B07A-4C0C-AEA9-9B663A28DFCB" width="1"></Object>
It’s followed by some JavaScript to detect whether that plug-in was loaded. If it was, then iTunes must be installed and it launches iTunes using the itms: protocol (just like the myapp: protocol in the example above).
The problem here is, you would have to write a browser plug-in.
It may be a good idea to look into using browser extensions for things like this.

Categories