Host Header Injection Analyzer
| Analyzer ID | Category | Severity | Time To Fix |
|---|---|---|---|
host-injection | 🛡️ Security | Medium | 10 minutes |
What This Checks
This analyzer detects Host header injection vulnerabilities where the application trusts the HTTP Host header without proper validation. It scans for three categories of issues:
Code-level checks:
- Direct
$_SERVERusage - Detects$_SERVER['HTTP_HOST'],$_SERVER['SERVER_NAME'], and$_SERVER['HTTP_X_FORWARDED_HOST']in application code - Unvalidated request methods - Flags
request()->getHost(),getHttpHost(),getSchemeAndHttpHost(),header('Host'),header('X-Forwarded-Host'),server('HTTP_HOST'), andheaders->get('host')calls without nearby validation (e.g.,in_array,===,config('app.url')checks) - URL methods in sensitive contexts - Flags
request()->url(),fullUrl(), androot()when used in security-sensitive operations such as redirects, cache keys, signed routes, or email notifications - Email URL generation - Detects URLs generated using the Host header near email-sending code (
Mail::to,->send(),new ...Mail()), which can lead to password reset poisoning
Configuration checks (only if unsafe code patterns are found):
- APP_URL configuration - Verifies
.env.exampledoes not use placeholder values andconfig/app.phpreferencesAPP_URL - TrustHosts middleware - Checks if the
TrustHostsmiddleware exists with a properly configuredhosts()method (L9/10), ortrustHosts()is called inbootstrap/app.php(L11/12) - Wildcard host patterns - Flags overly broad regex patterns (e.g.,
.*,.+, or plain*) that disable host validation entirely
Smart Detection
Configuration checks are only performed when unsafe code patterns are detected. If your application uses safe patterns like config('app.url') and url() consistently, the analyzer passes without raising configuration warnings. Additionally, URL::forceRootUrl() in a service provider is recognized as a global mitigation and suppresses configuration-level warnings.
Why It Matters
Host header injection allows attackers to manipulate the HTTP Host header to exploit applications that trust it:
- Password reset poisoning - Attacker changes the Host header so password reset emails contain malicious links pointing to the attacker's domain
- Cache poisoning - Manipulated Host headers cause cached pages to contain attacker-controlled URLs
- SSRF attacks - Host header manipulation can redirect internal requests to unintended targets
- Routing attacks - Applications that use the Host header for routing can be tricked into serving wrong content
- Phishing - Emails generated with untrusted Host values can be used for phishing attacks
How to Fix
Quick Fix (5 minutes)
Replace direct Host header usage with config('app.url'):
Before (❌):
// Vulnerable: trusting Host header for URL generation
$host = $_SERVER['HTTP_HOST'];
$resetUrl = "https://{$host}/password/reset/{$token}";
Mail::to($user)->send(new ResetPasswordMail($resetUrl));After (✅):
// Safe: using configured application URL
$resetUrl = config('app.url') . "/password/reset/{$token}";
Mail::to($user)->send(new ResetPasswordMail($resetUrl));Proper Fix (10 minutes)
- Use Laravel's URL generation helpers instead of manual Host header access:
Before (❌):
// Vulnerable: request()->getHost() without validation
$host = request()->getHost();
$callbackUrl = "https://{$host}/api/webhook/callback";
// Vulnerable: $_SERVER['SERVER_NAME'] directly
$domain = $_SERVER['SERVER_NAME'];
$link = "https://{$domain}/verify/{$token}";After (✅):
// Safe: use Laravel's url() helper (reads from config)
$callbackUrl = url('/api/webhook/callback');
// Safe: use route() helper for named routes
$link = route('verification.verify', ['token' => $token]);
// Safe: use config('app.url') for absolute URLs
$domain = config('app.url');- Configure trusted hosts:
For Laravel 9/10, publish and configure the TrustHosts middleware:
// app/Http/Middleware/TrustHosts.php
namespace App\Http\Middleware;
use Illuminate\Http\Middleware\TrustHosts as Middleware;
class TrustHosts extends Middleware
{
public function hosts(): array
{
return [
$this->allSubdomainsOfApplicationUrl(),
'^(.+\.)?yourdomain\.com$', // anchored regex, not glob syntax
];
}
}For Laravel 11/12, configure trusted hosts in bootstrap/app.php:
->withMiddleware(function (Middleware $middleware) {
$middleware->trustHosts(at: ['^(.+\.)?yourdomain\.com$']);
})Use Regex, Not Glob
TrustHosts passes host patterns directly to preg_match(). Glob-style patterns like *.yourdomain.com are invalid regexes and will silently fail, leaving host validation disabled. Always use anchored regex patterns: ^(.+\.)?yourdomain\.com$.
- Set APP_URL in production
.env:
# .env (production)
APP_URL=https://yourdomain.comReferences
- OWASP Host Header Injection
- Laravel TrustHosts Middleware
- CWE-644: Improper Neutralization of HTTP Headers
- Password Reset Poisoning (PortSwigger)
Related Analyzers
- CSRF Protection Analyzer - Ensures CSRF tokens are properly configured
- HSTS Header Analyzer - Validates HTTP Strict Transport Security header
- Cookie Domain Analyzer - Checks cookie domain configuration for security