ualibraries / Guide-on-the-Side

The University of Arizona Libraries will no longer provide support for Guide on the Side. The code will remain openly available; however, UAL can no longer provide code fixes or upgrades.
https://ualibraries.github.io/Guide-on-the-Side/about.html
Other
66 stars 48 forks source link

Investigate HTTPS/mixed content issues with F5 Load Balancer #148

Open simpsonw opened 8 years ago

simpsonw commented 8 years ago

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.

simpsonw commented 7 years ago

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.

simpsonw commented 7 years ago

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.

simpsonw commented 7 years ago

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).