43

I have a Facebook application that uses the Facebook Connect.js.

I am running my application over HTTPS. All content on the site is delivered from https:// with the exception of some content that must be included within Facebook's Connect.js

The problem is that I get warning messages saying that there are non-secure items within the page.

I've checked what scripts are being loaded using Chrome's Developer Tools / Network tab to see what files are being loaded and from where.

The only one I can see that is being loaded over HTTP and not over HTTPS is a file called http://static.ak.facebook.com/connect/canvas_proxy.php.

How can I force this file to use HTTPS?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
paperclip
  • 2,280
  • 6
  • 28
  • 39
  • I would notify Facebook of this issue. It is definitely an issue that they would need to resolve, perhaps by putting in a switch statement to check the protocol. – Zia Mar 16 '11 at 15:53

8 Answers8

54

TL;DR

set FB._https to true before calling FB.init. Like so:

FB._https = true;
FB.init({
    /* your app id and stuff */
});

Explanation

If you unminify the Facebook JavaScript SDK, you'll see that its basically an object literal with a bunch of properties. One of these properties is _https, which is a boolean. This property determines which set of URLs to use (stored in FB._domain) when making API requests. It seems as though Facebook keeps two sets of URLs for each type of API request -- a secure URL and and non-secure URL -- then uses a switch function called getDomain() to determine which to use when making requests.

The reason the JavaScript SDK causes security warnings is due to the way the FB._https property is defined. This is how it's currently defined as of 2011-8-24:

_https: (window.name.indexOf('_fb_https') > -1)

Apparently Facebook thinks that if the window.name property has _fb_https in it, then it must be a secure app. This is obviously incorrect. The real test should be something similar to this:

_https: window.location.protocol == "https:"

Unfortunately, the SDK is not open source or even well documented, so I can't submit a pull request for this change :P. In the short term, setting FB._https to true manually before calling FB.init should do the trick.

sakibmoon
  • 2,026
  • 3
  • 22
  • 32
Ralph Holzmann
  • 606
  • 7
  • 6
  • +1, this worked for us. Good find. Our office [submitted a pull request to this SDK](https://github.com/facebook/connect-js/pull/285), but it may or may not be the one that's in action right now. – Jimmy Sawczuk Sep 01 '11 at 20:09
  • 2
    Because of [this(so link)](http://stackoverflow.com/questions/7517670/fb-https-true-doesnt-play-nice-with-fb-canvas-setautoresize/7846888#7846888) I would change the `FB._https = true;` to `FB._https = (window.location.protocol == "https:");` like @simon-bachler said – Alexandros B Oct 21 '11 at 08:35
  • 1
    I'm still seeing the "secure content only" warning in IE9 with my iframe canvas app. Tried using both FB._https = true; and FB._https = (window.location.protocol == "https:"); – Ian Oct 23 '11 at 07:31
  • @Ian are you loading user profile pics? if so are you doing it over https? – Alexandros B Oct 25 '11 at 08:38
  • @Circadian The profile pics are coming over https. I think the issue has to do with passing a GET variable from the secure canvas page (see http://facebook.stackoverflow.com/questions/7866581/ie9-error-sec7111-https-security-is-compromised-after-redirect-plus-only-secu). Because of that I tried moving to an ajax method (see http://facebook.stackoverflow.com/questions/7886324/debugging-request-2-0-dialog-calling-request-function-within-function). If anyone can help me debug that issue, I'm THIS CLOSE to being ok. :-) – Ian Oct 25 '11 at 18:24
9

So this would give you the same protocol link:

FB._https = (window.location.protocol == "https:");
sbaechler
  • 1,329
  • 14
  • 21
  • Private method access will become deprecated and removed on June 6th 2012: http://developers.facebook.com/blog/post/2012/05/16/platform-updates--operation-developer-love/ So this fix will no longer work. Apparently the bug had been fixed by Facebook. – sbaechler May 17 '12 at 16:49
8

I came across this problem a few days ago. My entire application was using HTTPS and my issue was only profile pictures being loaded over HTTP... My quick and dirty fix was to manually replace all the profile pictures' domain names. For example,

str_replace('http://profile.ak.fbcdn.net','https://fbcdn-profile-a.akamaihd.net',$user['pic_square']);

You'll have to check and see what URL your profile pictures have. I'd assume they are not coming from exactly the same place. View the URL of your own profile picture and substitute for what I have at https://fbcdn-profile-a.akamaihd.net.

After looking harder at the Facebook documentation:

If you need a picture to be returned over a secure connection, you can set the return_ssl_resources argument to 1: https://graph.facebook.com/4/picture?return_ssl_resources=1.

I found an additional parameter called return_ssl_resources, and when passed with true, it returns profile pictures using HTTPS.

$fql = "SELECT uid, name, pic_square FROM user WHERE uid=me()";

$param = array( 'method' => 'fql.query', 'query' => $fql, 'return_ssl_resources'=>1);

$fbuser = $facebook->api($param);

It worked like a charm, and I stopped getting the mixed security warnings. I hope this helps!

sakibmoon
  • 2,026
  • 3
  • 22
  • 32
Lix
  • 47,311
  • 12
  • 103
  • 131
2

Adding to Ralph Holzmann and Simon Bächler, the following is an even harder-hitting fix for when FB._https alone does not do the trick;

FB._https = (window.location.protocol == "https:");
FB.init({
    ...
});
if (FB._https && window == window.parent) {
    if (FB._domain && FB._domain.staticfb && FB._domain.https_staticfb)
        FB._domain.staticfb = FB._domain.https_staticfb;
}

See also FB.Arbiter.inform() { ... FB.getDomain((d?'https_':'')+'staticfb',true) ... } where d=window!=window.parent&&... as of 2012-Feb-10.

sakibmoon
  • 2,026
  • 3
  • 22
  • 32
Carl Krig
  • 161
  • 7
1

It look like FB._https as been replaced by :

FB._secure = (window.location.protocol == "https:");
0

I was having a similar problem (fb comments not working in secure mode). This solves it - just reference the javascript file via https:

<script type="text/javascript" src="https://connect.facebook.net/en_US/all.js"></script>

Or don't specify the scheme to work for both:

<script type="text/javascript" src="//connect.facebook.net/en_US/all.js"></script>
kraigh
  • 1
0

This seems to be caused by this Facebook bug.

Also see this forum post.

That bug was marked as resolved on 3/16, but I am still observing non-https requests to canvas_proxy.php. Hopefully this will be fixed for real soon...

Mirko Froehlich
  • 12,006
  • 4
  • 27
  • 23
0

On a sidenote, if you have doc-type declarations on your HTML page like the folllowing, the reference to "http://www.w3.org" can also bring up the content warning error in Internet Explorer.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
sakibmoon
  • 2,026
  • 3
  • 22
  • 32
Jim Jose
  • 1,319
  • 11
  • 17