Skip to content
Pro Analyzer — Available with ShieldCI Pro

Host Header Injection Analyzer

Analyzer IDCategorySeverityTime To Fix
host-injection🛡️ SecurityHigh10 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 $_SERVER usage - 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'), and headers->get('host') calls without nearby validation (e.g., in_array, ===, config('app.url') checks)
  • URL methods in sensitive contexts - Flags request()->url(), fullUrl(), and root() 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.example does not use placeholder values and config/app.php references APP_URL
  • TrustHosts middleware - Checks if the TrustHosts middleware exists with a properly configured hosts() method (L9/10), or trustHosts() is called in bootstrap/app.php (L11/12)
  • Wildcard host patterns - Flags overly broad regex patterns (e.g., .*, .+, or plain *) that disable host validation entirely

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 (❌):

php
// 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 (✅):

php
// Safe: using configured application URL
$resetUrl = config('app.url') . "/password/reset/{$token}";

Mail::to($user)->send(new ResetPasswordMail($resetUrl));

Proper Fix (10 minutes)

  1. Use Laravel's URL generation helpers instead of manual Host header access:

Before (❌):

php
// 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 (✅):

php
// 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');
  1. Configure trusted hosts:

For Laravel 9/10, publish and configure the TrustHosts middleware:

php
// 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:

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$.

  1. Set APP_URL in production .env:
ini
# .env (production)
APP_URL=https://yourdomain.com

References