In my CakePHP 3.10 application, the redirects are changing the protocols and breaking the app. This is being deployed to an App Service (PHP 7.4) in Azure.
I’m not seeing this on another LAMP stack (RHEL, Apache 2.4, PHP 7.3, https configured) on premise.
Example, logging out of the application.
public function logout() { $this->getRequest()->getSession()->write('isAdmin',false); $this->Flash->success(__('You are now logged out.')); return $this->redirect($this->Auth->logout()); }
During inspection of the traffic (via Edge’s > Inspect > Network), here’s what I see (notice Response Header Location change from https to http):
General
Request URL: https://my.domain.com/users/logout Request Method: GET Status Code: 302 Found Remote Address: my.ip.here:443 Referrer Policy: strict-origin-when-cross-origin
Response Headers
Cache-Control: no-store, no-cache, must-revalidate Content-Length: 0 Content-Type: text/html; charset=UTF-8 Date: Sun, 19 Dec 2021 13:08:05 GMT Expires: Thu, 19 Nov 1981 08:52:00 GMT Location: http://my.domain.com/ Pragma: no-cache Server: Apache Set-Cookie: CAKEPHP=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/; HttpOnly Set-Cookie: CAKEPHP=c2be7c7d45c9418b06356bd95796ff8f; path=/; HttpOnly X-Powered-By: PHP/7.4.24
Request Headers
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.9 Connection: keep-alive Cookie: csrfToken=09206701259fb54445122132512cf0e8f00cf2ac2f2cf42a34a49cd221b9e797c36d919696daad8d2fc77a0373e417e5e59a89a0cacc9c408ebeede1fc0b4446; CAKEPHP=c6ebd1412956de948b4857c4a0791f04 DNT: 1 Host: my.domain.com Referer: https://my.domain.com/ sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Microsoft Edge";v="96" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "Windows" Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: same-origin Sec-Fetch-User: ?1 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62
Advertisement
Answer
Like many load balancers, the Azure ones also like to terminate SSL, so that the requests that are reaching PHP will be unencrypted, making the env('HTTPS')
lookup fail that CakePHP applications use by default to build the full base URL.
/* * Set the full base URL. * This URL is used as the base of all absolute links. * * If you define fullBaseUrl in your config file you can remove this. */ if (!Configure::read('App.fullBaseUrl')) { $s = null; if (env('HTTPS')) { $s = 's'; } $httpHost = env('HTTP_HOST'); if (isset($httpHost)) { Configure::write('App.fullBaseUrl', 'http' . $s . '://' . $httpHost); } unset($httpHost, $s); }
https://github.com/cakephp/app/blob/3.10.1/config/bootstrap.php#L131-L148
The linked Azure docs suggest checking the HTTP_X_FORWARDED_PROTO
header instead, which is being populated by the load balancer, but you need to take into account that depending on the environment that the application runs in, this header could also have been set by the client, so I wouldn’t generally recommend using it.
I would instead suggest to hardcode the protocol, or better yet, set the complete full base URL manually (at least in the past HTTP_HOST
has been a problem too, as some servers accepted custom values sent from the client), eg:
Configure::write('App.fullBaseUrl', 'https://' . $httpHost);
or set App.fullBaseUrl
in your config/app.php
(or config/app_local.php
).