Skip to content

Commit d4574fa

Browse files
committed
Security: Prevent Host Header Injection attacks
This commit fixes a critical security vulnerability that allows Host Header Injection attacks, which can be used to hijack password reset tokens and other security-critical operations. Changes: 1. Updated config/app.php: - Changed App.fullBaseUrl default from 'false' to env('APP_FULL_BASE_URL') - Enhanced documentation to explicitly warn about security implications - Added clear instructions for proper configuration 2. Updated config/bootstrap.php: - Added security validation that throws exception in production if App.fullBaseUrl is not configured - Retained HTTP_HOST fallback ONLY for development mode - Added explicit security warnings in comments 3. Updated config/.env.example: - Added APP_FULL_BASE_URL with security documentation - Provides example value for developers to configure Impact: - Development: No breaking changes (HTTP_HOST still used as fallback) - Production: Applications MUST set APP_FULL_BASE_URL or will fail with clear error message explaining the security requirement Attack Vector: Without this fix, attackers can send malicious Host headers in password reset requests, causing the application to generate reset links pointing to attacker-controlled domains. When victims click these links, attackers capture valid reset tokens and can compromise accounts. References: - OWASP Host Header Injection - https://portswigger.net/web-security/host-header 🤖 Generated with Claude Code
1 parent 99389c9 commit d4574fa

File tree

3 files changed

+31
-16
lines changed

3 files changed

+31
-16
lines changed

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: 7 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'),
6163
'imageBaseUrl' => 'img/',
6264
'cssBaseUrl' => 'css/',
6365
'jsBaseUrl' => 'js/',

config/bootstrap.php

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -144,24 +144,34 @@
144144
}
145145

146146
/*
147-
* Set the full base URL.
147+
* SECURITY: Validate and set the full base URL.
148148
* This URL is used as the base of all absolute links.
149-
* Can be very useful for CLI/Commandline applications.
149+
*
150+
* IMPORTANT: In production, App.fullBaseUrl MUST be explicitly configured to prevent
151+
* Host Header Injection attacks. Relying on the HTTP_HOST header can allow attackers
152+
* to hijack password reset tokens and other security-critical operations.
153+
*
154+
* Set APP_FULL_BASE_URL in your environment variables or configure App.fullBaseUrl
155+
* in config/app.php or config/app_local.php
156+
*
157+
* Example: APP_FULL_BASE_URL=https://yourdomain.com
150158
*/
151159
$fullBaseUrl = Configure::read('App.fullBaseUrl');
152160
if (!$fullBaseUrl) {
161+
if (!Configure::read('debug')) {
162+
throw new \Cake\Core\Exception\CakeException(
163+
'SECURITY: App.fullBaseUrl is not configured. ' .
164+
'This is required in production to prevent Host Header Injection attacks. ' .
165+
'Set APP_FULL_BASE_URL environment variable or configure App.fullBaseUrl in config/app.php'
166+
);
167+
}
168+
153169
/*
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
170+
* Development mode fallback: Use HTTP_HOST for convenience.
171+
* WARNING: This is ONLY safe in development. Never use this pattern in production!
160172
*/
161-
$trustProxy = false;
162-
163173
$s = null;
164-
if (env('HTTPS') || ($trustProxy && env('HTTP_X_FORWARDED_PROTO') === 'https')) {
174+
if (env('HTTPS')) {
165175
$s = 's';
166176
}
167177

0 commit comments

Comments
 (0)