Recently it came to our attention a page loaded using HTTPS was being declared as a security risk due to included images, css and javascript files being loaded via HTTP. A developer had recently made some user interface improvements on the page, so naturally I thought he had coded the new images to load with HTTP, causing the SSL warning. After much grepping through includes and header files the cause turned out to be an incorrectly set base href tag in the header. We were using PHP's getenv command to check for the existence of the ssl variable being set - and thus setting the base href appropriately. Upon examination of the output of phpinfo() for a page loaded with HTTPS - the ssl environmental variable was not present. The lack of the variable seemed odd, so I checked the output of phpinfo() on our QA machine - it appeared here - and production and QA share the same code base. Hmmmmm.
Now what I haven't told you is our production web servers are load balanced by pound. Some googling revealed the pound decrypts HTTPS requests before dispatching them to a backend www server (so that's why you define the SSL certificate in pound.cfg. BTW - the .pem file pound wants to see is the concatenation of the site key + the site certificate + the intermidiate certificate. I lost a day trying to find this info.). Ok, mystery solved. Now then how to detect on the www servers the original request was via HTTPS and not HTTP? More googling... turns out you can insert a HTTP header into the request pound sends to a backend server. Add this line in pound.cfg:
AddHeader "X-Forwarded-Proto: https"
HeadRemove "X-Forwarded-Proto"
Now we can check for X-Forwarded-Proto in the $_SERVER scope. Wait there's more - it's called HTTP_X_FORWARDED_FOR now, so:
$request_type = if ($_SERVER['HTTP_X_FORWARDED_FOR']) ? 'HTTPS' : 'HTTP';
And that's it, problem solved.
No comments:
Post a Comment