Non-secure items loaded by Facebook’s JavaScript SDK via HTTPS

Facebook appears to maintain separate URLs for each API request type – one secure and one non-secure – and employs a switch function, known as , to determine which URL to use for each request. While react-facebook-login and the Facebook JavaScript SDK work seamlessly on web browsers, an error occurred when I attempted to use them on a mobile device. The URLs associated with the error looked like this: . To resolve this issue, I added localhost to my App Domains, but I’m unsure which domain(s) I should add.


Question:

My Facebook app utilizes Facebook Connect.js.

My application is utilizing HTTPS and all of the site’s content is being sourced from

https://

. However, there are certain pieces of content that need to be incorporated within Facebook’s

Connect.js

.

The issue at hand is receiving cautionary notices that non-secure elements are present on the page.

By utilizing Chrome’s Developer Tools / Network tab, I have examined the scripts that are currently being loaded and their sources.

The file named

http://static.ak.facebook.com/connect/canvas_proxy.php

is the only one being loaded via HTTP instead of HTTPS.

What measures can I take to ensure that this file utilizes HTTPS?


Solution 1:


TL;DR

Before invoking

FB.init

, assign

true

to

FB._https

. Here’s an example:

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


Explanation

Upon unminifying the
Facebook javascript
SDK, you can observe that it is an object literal with multiple properties. One of these properties is a boolean named

_https

, which determines the set of URLs to use for API requests. The URLs are stored in

FB._domain

, and Facebook maintains two sets of URLs for each type of API request – one secure and one non-secure. To determine which URL set to use, a switch function called

getDomain()

is utilized while making the API requests.

The security warnings prompted by
JavaScript SDK
are a result of the definition of the

FB._https

property, which has been in place since August 24th, 2011.


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

Facebook’s assumption that an app is secure just because it contains

_fb_https

within the

window.name

property is flawed. A more accurate evaluation criterion should be applied.


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

Regrettably, the SDK lacks open-source availability and adequate documentation, which prevents me from proposing a pull request for this modification. Nonetheless, a temporary solution would be to manually adjust the value of

FB._https

to

true

before invoking

FB.init

. This approach should suffice for the time being.


Solution 2:


This would provide you with an identical protocol link.

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


Solution 3:


Recently, I encountered a problem where my application was using HTTPS, but the profile pictures were being loaded over HTTP. To resolve this issue, I manually substituted the domain names of all the profile pictures.

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

Verify the URL of your profile pictures as they may not be originating from the same source. To replace the URL at

https://fbcdn-profile-a.akamaihd.net

, examine the URL of your profile picture.

Upon conducting a more thorough examination of the Facebook documentation.

To ensure a secure connection while retrieving an image, you may specify the return_ssl_resources parameter as 1 in the URL. For instance, https://graph.facebook.com/4/picture?return_ssl_resources=1.

I came across a new parameter named

return_ssl_resources

, which, in conjunction with

true

, retrieves profile pictures through 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);

After applying the solution, the mixed security warnings no longer appeared. I am glad that it worked effectively and may it be helpful to you as well.


Solution 4:

In addition to Ralph Holzmann and Simon B├Ąchler’s recommendations, there is a more forceful solution available if using “https” alone does not suffice for fixing the issue with FB.

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;
}

As of February 10, 2012, you can also refer to FB.Arbiter.inform() { … FB.getDomain((d?’https_’:”)+’staticfb’,true) … } where d=window!=window.parent&&…

Frequently Asked Questions

Posted in Ssl