CakePHP (all versions that I've seen) check against $_SERVER['HTTPS'] to see whether a request has been made over HTTPS instead of plain HTTP.

I'm using nginx as a load balancer, behind which are the Apache application servers. Since the SSL connection terminates at the load balancer, $_SERVER['HTTPS'] is not set as far as CakePHP is concerned.

I'd like to find a secure way to detect HTTPS on the app servers.

So far, I've put this into my CakePHP configuration:

$request_headers = getallheaders();
if ( (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']) || ( isset($request_headers['X-Forwarded-Proto']) && $request_headers['X-Forwarded-Proto'] == 'https' ) ) {

    $ssl = true;

    // overwrite environment vars (ugly) since CakePHP won't honour X-Forwarded-Proto
    $_SERVER['HTTPS'] = 'on';
    $_ENV['HTTPS'] = 'on';

} else {
    $ssl = false;
}

And then in the nginx configuration, I've used proxy_set_header X-Forwarded-Proto https; to add the flag to any requests between the load balancer and the back-end application servers.

This works perfectly fine, but anyone making a direct request to the app servers could fool them into thinking they are browsing over SSL when they're not. I'm not sure whether this is a security risk, but it doesn't seem like a good idea.

Is it a security risk? What's the better solution?

Since using X-Forwarded-Proto seems like something of a standard, the solution may be a good patch to be submitted to the CakePHP core, so I think any answer can legitimately involve editing core files too.

Edit
Report