ualibraries/Guide-on-the-Side

Investigate HTTPS/mixed content issues with F5 Load Balancer

Opened this issue · 3 comments

We've gotten reports that HTTPS isn't working everywhere and people are getting mixed content errors. Find where the problems are and fix them.

To add a little more context, this issue in question was observed at https://archweb.luc.edu/guide_on_the_side/. It seems to be caused by the <base> tag's href property being set to http rather than https. Specifying the full base URL with https in app/Config/core.php seems to be a workaround, e.g.

Configure::write('App.fullBaseUrl', "https://example.com/guide_on_the_side/");

As for the underlying cause, App.fullBaseUrl is set in lib/Cake/bootstrap.php on line 166:

/**
 * Full URL prefix
 */
if (!defined('FULL_BASE_URL')) {
    $s = null;
    if (env('HTTPS')) {
        $s = 's';
    }

    $httpHost = env('HTTP_HOST');

    if (isset($httpHost)) {
        define('FULL_BASE_URL', 'http' . $s . '://' . $httpHost);
        Configure::write('App.fullBaseUrl', FULL_BASE_URL);
    }
    unset($httpHost, $s);
}

env() is a convenience function CakePHP provides to get environment information from PHP. In the case of HTTPS, it's checking the $_SERVER superglobal. From around line 292 in lib/Cake/basics.php:

    function env($key) {
        if ($key === 'HTTPS') {
            if (isset($_SERVER['HTTPS'])) {
                return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
            }
            return (strpos(env('SCRIPT_URI'), 'https://') === 0);
        }
...

It may be worth investigate if there are any quirks around $_SERVER['HTTPS'] or $_SERVER['SCRIPT_URI'] that could cause trouble.

I figured out a way of reproducing the issue mentioned, albeit one that requires having your php.ini set up in a specific way. It involves the directive variables_order. From php.net:

Sets the order of the EGPCS (Environment, Get, Post, Cookie, and Server) variable parsing. For example, if variables_order is set to "SP" then PHP will create the superglobals $_SERVER and $_POST, but not create $_ENV, $_GET, and $_COOKIE. Setting to "" means no superglobals will be set.

So if you set variables_order to a value that doesn't contain 's', then the $_SERVER superglobal isn't in scope and CakePHP in unable to determine whether or not things are running over HTTPS.

It looks like this is an issue with the way F5 load balancer works. As I understand it, F5 handles all the HTTPS requests coming in and then offloads them as HTTP requests to the application servers. This causes a problem because as far as Guide on the Side knows, PHP is not using HTTPS. @caosborne89 found an article from Lullabot where they discussed inserting a special header via an iRule in F5 and then detecting that header in the application code (https://www.lullabot.com/articles/setting-up-ssl-offloading-termination-on-an-f5-bigip-load-balancer).

That's something we could look into but I'd want to figure out some kind of way that we could have an F5 setup for testing purposes. It looks like AWS will offer some F5 stuff, so that could be a solution (https://aws.amazon.com/marketplace/seller-profile?id=74d946f0-fa54-4d9f-99e8-ff3bd8eb2745).