|
35 | 35 | use Cake\Cache\Cache; |
36 | 36 | use Cake\Core\Configure; |
37 | 37 | use Cake\Core\Configure\Engine\PhpConfig; |
| 38 | +use Cake\Core\Exception\CakeException; |
38 | 39 | use Cake\Datasource\ConnectionManager; |
39 | 40 | use Cake\Error\ErrorTrap; |
40 | 41 | use Cake\Error\ExceptionTrap; |
|
44 | 45 | use Cake\Mailer\TransportFactory; |
45 | 46 | use Cake\Routing\Router; |
46 | 47 | use Cake\Utility\Security; |
| 48 | +use Detection\MobileDetect; |
47 | 49 | use function Cake\Core\env; |
48 | 50 |
|
49 | 51 | /* |
|
83 | 85 | try { |
84 | 86 | Configure::config('default', new PhpConfig()); |
85 | 87 | Configure::load('app', 'default', false); |
86 | | -} catch (\Exception $e) { |
| 88 | +} catch (Exception $e) { |
87 | 89 | exit($e->getMessage() . "\n"); |
88 | 90 | } |
89 | 91 |
|
|
144 | 146 | } |
145 | 147 |
|
146 | 148 | /* |
147 | | - * Set the full base URL. |
| 149 | + * SECURITY: Validate and set the full base URL. |
148 | 150 | * 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 |
150 | 160 | */ |
151 | 161 | $fullBaseUrl = Configure::read('App.fullBaseUrl'); |
152 | 162 | if (!$fullBaseUrl) { |
| 163 | + $httpHost = env('HTTP_HOST'); |
| 164 | + |
153 | 165 | /* |
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. |
160 | 168 | */ |
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 | + ); |
166 | 175 | } |
167 | 176 |
|
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 | + */ |
169 | 181 | if ($httpHost) { |
| 182 | + $s = null; |
| 183 | + if (env('HTTPS') || env('HTTP_X_FORWARDED_PROTO') === 'https') { |
| 184 | + $s = 's'; |
| 185 | + } |
170 | 186 | $fullBaseUrl = 'http' . $s . '://' . $httpHost; |
171 | 187 | } |
172 | 188 | unset($httpHost, $s); |
|
193 | 209 | * and the mobiledetect package from composer.json. |
194 | 210 | */ |
195 | 211 | ServerRequest::addDetector('mobile', function ($request) { |
196 | | - $detector = new \Detection\MobileDetect(); |
| 212 | + $detector = new MobileDetect(); |
197 | 213 |
|
198 | 214 | return $detector->isMobile(); |
199 | 215 | }); |
200 | 216 | ServerRequest::addDetector('tablet', function ($request) { |
201 | | - $detector = new \Detection\MobileDetect(); |
| 217 | + $detector = new MobileDetect(); |
202 | 218 |
|
203 | 219 | return $detector->isTablet(); |
204 | 220 | }); |
|
0 commit comments