From 4f25d4e8af4cd0717286913213256fe6659fa4f7 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Tue, 3 Nov 2026 22:58:47 -0500 Subject: [PATCH 1/2] Fix weakness to host header manipulation For a long time we used `HTTP_HOST` as a fallback for `fullBaseUrl`, but doing so makes applications vulnerable to host header injection. In #1071, the `HostHeaderMiddleware` was introduced to address this weakness. However, in #1076 the debug condition was removed to address feedback, but also re-opened the weakness to host-header injection. These changes restore the `debug` check around automatically trusting `HTTP_HOST`. The `HostHeaderMiddleware` is applied *after* error handling so configuration mistakes are easy to identify. Thanks to Jaro Varga for reporting this. --- config/bootstrap.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/config/bootstrap.php b/config/bootstrap.php index e05ec9fe2..60984e286 100644 --- a/config/bootstrap.php +++ b/config/bootstrap.php @@ -38,6 +38,7 @@ use Cake\Datasource\ConnectionManager; use Cake\Error\ErrorTrap; use Cake\Error\ExceptionTrap; +use Cake\Http\Exception\ForbiddenException; use Cake\Http\ServerRequest; use Cake\Log\Log; use Cake\Mailer\Mailer; @@ -165,21 +166,22 @@ */ $fullBaseUrl = Configure::read('App.fullBaseUrl'); if (!$fullBaseUrl) { - $httpHost = env('HTTP_HOST'); - /* * Development mode fallback: Use HTTP_HOST for convenience. * WARNING: This is ONLY safe in development. In production, the * HostHeaderMiddleware will reject requests when fullBaseUrl is not configured. */ - if ($httpHost) { - $s = null; - if (env('HTTPS') || env('HTTP_X_FORWARDED_PROTO') === 'https') { - $s = 's'; + if (Configure::read('debug')) { + $httpHost = env('HTTP_HOST'); + if ($httpHost) { + $s = null; + if (env('HTTPS') || env('HTTP_X_FORWARDED_PROTO') === 'https') { + $s = 's'; + } + $fullBaseUrl = 'http' . $s . '://' . $httpHost; } - $fullBaseUrl = 'http' . $s . '://' . $httpHost; + unset($httpHost, $s); } - unset($httpHost, $s); } if ($fullBaseUrl) { Router::fullBaseUrl($fullBaseUrl); From 7fb4cb058720a54b8f46fbdfc64ba82172735bfe Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sun, 8 Nov 2026 23:36:12 -0500 Subject: [PATCH 2/2] Simplify logic to create scheme --- config/bootstrap.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/config/bootstrap.php b/config/bootstrap.php index 60984e286..6ac400184 100644 --- a/config/bootstrap.php +++ b/config/bootstrap.php @@ -174,13 +174,10 @@ if (Configure::read('debug')) { $httpHost = env('HTTP_HOST'); if ($httpHost) { - $s = null; - if (env('HTTPS') || env('HTTP_X_FORWARDED_PROTO') === 'https') { - $s = 's'; - } - $fullBaseUrl = 'http' . $s . '://' . $httpHost; + $scheme = env('HTTPS') || env('HTTP_X_FORWARDED_PROTO') === 'https' ? 'https' : 'http'; + $fullBaseUrl = $scheme . '://' . $httpHost; } - unset($httpHost, $s); + unset($httpHost, $scheme); } } if ($fullBaseUrl) {