Skip to content

Commit 6e26611

Browse files
committed
Merge branch 'refs/heads/5.x' into 5.next
2 parents 9faffeb + 9d4dccb commit 6e26611

File tree

5 files changed

+48
-40
lines changed

5 files changed

+48
-40
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ jobs:
2323
include:
2424
- php-version: '8.2'
2525
dependencies: 'lowest'
26-
- php-version: '8.4'
26+
- php-version: '8.5'
2727
dependencies: 'highest'
2828
- php-version: '8.5'
2929
dependencies: 'highest'
3030

3131
steps:
32-
- uses: actions/checkout@v5
32+
- uses: actions/checkout@v6
3333

3434
- name: Setup PHP
3535
uses: shivammathur/setup-php@v2
@@ -58,7 +58,7 @@ jobs:
5858
runs-on: ubuntu-24.04
5959

6060
steps:
61-
- uses: actions/checkout@v5
61+
- uses: actions/checkout@v6
6262

6363
- name: Setup PHP
6464
uses: shivammathur/setup-php@v2

config/.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ export DEBUG="true"
1818
export APP_ENCODING="UTF-8"
1919
export APP_DEFAULT_LOCALE="en_US"
2020
export APP_DEFAULT_TIMEZONE="UTC"
21+
# SECURITY: Set this to your domain to prevent Host Header Injection attacks
22+
# This is REQUIRED in production for password resets and other security features
23+
export APP_FULL_BASE_URL="https://yourdomain.com"
2124
export SECURITY_SALT="__SALT__"
2225

2326
# Uncomment these to define cache configuration via environment variables.

config/app.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@
3636
* /.htaccess
3737
* /webroot/.htaccess
3838
* And uncomment the baseUrl key below.
39-
* - fullBaseUrl - A base URL to use for absolute links. When set to false (default)
40-
* CakePHP generates required value based on `HTTP_HOST` environment variable.
41-
* However, you can define it manually to optimize performance or if you
42-
* are concerned about people manipulating the `Host` header.
39+
* - fullBaseUrl - SECURITY: A base URL to use for absolute links.
40+
* IMPORTANT: This MUST be set in production to prevent Host Header Injection attacks
41+
* that can compromise password reset and other security-critical features.
42+
* Set this via APP_FULL_BASE_URL environment variable or directly in config.
43+
* Example: 'https://yourdomain.com'
44+
* When not set, the application will throw an exception in production mode.
4345
* - imageBaseUrl - Web path to the public images/ directory under webroot.
4446
* - cssBaseUrl - Web path to the public css/ directory under webroot.
4547
* - jsBaseUrl - Web path to the public js/ directory under webroot.
@@ -57,7 +59,7 @@
5759
'webroot' => 'webroot',
5860
'wwwRoot' => WWW_ROOT,
5961
//'baseUrl' => env('SCRIPT_NAME'),
60-
'fullBaseUrl' => false,
62+
'fullBaseUrl' => env('APP_FULL_BASE_URL', false),
6163
'imageBaseUrl' => 'img/',
6264
'cssBaseUrl' => 'css/',
6365
'jsBaseUrl' => 'js/',
@@ -189,6 +191,8 @@
189191
* By default atom, emacs, macvim, phpstorm, sublime, textmate, and vscode are
190192
* available. You can add additional editor link formats using
191193
* `Debugger::addEditor()` during your application bootstrap.
194+
* - `editorBasePath` - The base path to your project for editor integration.
195+
* Used to generate file links in stack traces.
192196
* - `outputMask` A mapping of `key` to `replacement` values that
193197
* `Debugger` should replace in dumped data and logs generated by `Debugger`.
194198
*/

config/bootstrap.php

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
use Cake\Cache\Cache;
3636
use Cake\Core\Configure;
3737
use Cake\Core\Configure\Engine\PhpConfig;
38+
use Cake\Core\Exception\CakeException;
3839
use Cake\Datasource\ConnectionManager;
3940
use Cake\Error\ErrorTrap;
4041
use Cake\Error\ExceptionTrap;
@@ -44,6 +45,7 @@
4445
use Cake\Mailer\TransportFactory;
4546
use Cake\Routing\Router;
4647
use Cake\Utility\Security;
48+
use Detection\MobileDetect;
4749
use function Cake\Core\env;
4850

4951
/*
@@ -83,7 +85,7 @@
8385
try {
8486
Configure::config('default', new PhpConfig());
8587
Configure::load('app', 'default', false);
86-
} catch (\Exception $e) {
88+
} catch (Exception $e) {
8789
exit($e->getMessage() . "\n");
8890
}
8991

@@ -144,29 +146,43 @@
144146
}
145147

146148
/*
147-
* Set the full base URL.
149+
* SECURITY: Validate and set the full base URL.
148150
* This URL is used as the base of all absolute links.
149-
* Can be very useful for CLI/Commandline applications.
151+
*
152+
* IMPORTANT: In production, App.fullBaseUrl MUST be explicitly configured to prevent
153+
* Host Header Injection attacks. Relying on the HTTP_HOST header can allow attackers
154+
* to hijack password reset tokens and other security-critical operations.
155+
*
156+
* Set APP_FULL_BASE_URL in your environment variables or configure App.fullBaseUrl
157+
* in config/app.php or config/app_local.php
158+
*
159+
* Example: APP_FULL_BASE_URL=https://yourdomain.com
150160
*/
151161
$fullBaseUrl = Configure::read('App.fullBaseUrl');
152162
if (!$fullBaseUrl) {
163+
$httpHost = env('HTTP_HOST');
164+
153165
/*
154-
* When using proxies or load balancers, SSL/TLS connections might
155-
* get terminated before reaching the server. If you trust the proxy,
156-
* you can enable `$trustProxy` to rely on the `X-Forwarded-Proto`
157-
* header to determine whether to generate URLs using `https`.
158-
*
159-
* See also https://book.cakephp.org/5/en/controllers/request-response.html#trusting-proxy-headers
166+
* Only enforce fullBaseUrl requirement when we're in a web request context.
167+
* This allows CLI tools (like PHPStan) to load the bootstrap without throwing.
160168
*/
161-
$trustProxy = false;
162-
163-
$s = null;
164-
if (env('HTTPS') || ($trustProxy && env('HTTP_X_FORWARDED_PROTO') === 'https')) {
165-
$s = 's';
169+
if (!Configure::read('debug') && $httpHost) {
170+
throw new CakeException(
171+
'SECURITY: App.fullBaseUrl is not configured. ' .
172+
'This is required in production to prevent Host Header Injection attacks. ' .
173+
'Set APP_FULL_BASE_URL environment variable or configure App.fullBaseUrl in config/app.php',
174+
);
166175
}
167176

168-
$httpHost = env('HTTP_HOST');
177+
/*
178+
* Development mode fallback: Use HTTP_HOST for convenience.
179+
* WARNING: This is ONLY safe in development. Never use this pattern in production!
180+
*/
169181
if ($httpHost) {
182+
$s = null;
183+
if (env('HTTPS') || env('HTTP_X_FORWARDED_PROTO') === 'https') {
184+
$s = 's';
185+
}
170186
$fullBaseUrl = 'http' . $s . '://' . $httpHost;
171187
}
172188
unset($httpHost, $s);
@@ -193,12 +209,12 @@
193209
* and the mobiledetect package from composer.json.
194210
*/
195211
ServerRequest::addDetector('mobile', function ($request) {
196-
$detector = new \Detection\MobileDetect();
212+
$detector = new MobileDetect();
197213

198214
return $detector->isMobile();
199215
});
200216
ServerRequest::addDetector('tablet', function ($request) {
201-
$detector = new \Detection\MobileDetect();
217+
$detector = new MobileDetect();
202218

203219
return $detector->isTablet();
204220
});

tests/bootstrap.php

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
use Cake\Chronos\Chronos;
1919
use Cake\Core\Configure;
20-
use Cake\Datasource\ConnectionManager;
2120
use Cake\TestSuite\ConnectionHelper;
2221
use Migrations\TestSuite\Migrator;
2322

@@ -35,20 +34,6 @@
3534
Configure::write('App.fullBaseUrl', 'http://localhost');
3635
}
3736

38-
// DebugKit skips settings these connection config if PHP SAPI is CLI / PHPDBG.
39-
// But since PagesControllerTest is run with debug enabled and DebugKit is loaded
40-
// in application, without setting up these config DebugKit errors out.
41-
ConnectionManager::setConfig('test_debug_kit', [
42-
'className' => 'Cake\Database\Connection',
43-
'driver' => 'Cake\Database\Driver\Sqlite',
44-
'database' => TMP . 'debug_kit.sqlite',
45-
'encoding' => 'utf8',
46-
'cacheMetadata' => true,
47-
'quoteIdentifiers' => false,
48-
]);
49-
50-
ConnectionManager::alias('test_debug_kit', 'debug_kit');
51-
5237
// Fixate now to avoid one-second-leap-issues
5338
Chronos::setTestNow(Chronos::now());
5439

0 commit comments

Comments
 (0)