I am willing to prevent host header attack in my laravel 9 app. I am using this command in terminal to test for that attack - curl http://127.0.0.1:8000 -H "Host: evil.com".
After searching on internet i have enabled this \App\Http\Middleware\TrustHosts::class middleware in kernel.php file.
Even i have created my own middleware to check for host header like this
<?php
namespace App\Http\Middleware;
use Closure;
class HostHeaderValidationMiddleware
{
public function handle($request, Closure $next)
{
$expectedDomain = '127.0.0.1';
// echo $_SERVER['HTTP_HOST'];
// echo "<br>";
// echo $_SERVER['SERVER_NAME'];exit;
// Validate and sanitize the host header
if ($request->getHost() !== $expectedDomain || $_SERVER['SERVER_NAME'] !== $expectedDomain) {
abort(400, 'Invalid request.');
}
// Validating referer header
$referer = $request->headers->get('Referer');
if ($referer && parse_url($referer, PHP_URL_HOST) !== $expectedDomain) {
abort(400, 'Invalid Referer header.');
}
return $next($request);
}
}
But after running this command it is not even going into this middleware it is giving this output in terminal
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="refresh" content="0;url='http://evil.com/login'" />
<title>Redirecting to http://evil.com/login</title>
</head>
<body>
Redirecting to <a href="http://evil.com/login">http://evil.com/login</a>.
</body>
</html>
Is ther any other way to prevent host header attack in Laravel or PHP
You can skip your own middleware and use the laravel trusted hosts middleware (The one shipped with laravel which you enabled).
Make sure that in the middleware you have defined your hosts, something like this:
Alternativley you can skip adding localhost and use the defaults like this:
In that case you need to make sure that
APP_URLin your.envfile is correct. Then only requests to theAPP_URLhost (and it's subdomains) are allowed.Note: That your port 8000 suggests you are running laravel with
php artisan serve. If your app islocallaravel will skip the trusted hosts checks. (If you look into theIlluminate\Http\Middleware\TrustHostsclass you will see this check:So make sure in your
.envfileAPP_ENVis NOT set tolocal. Set it to something likeproductioninstead:When you have followed my instructions above
curl http://127.0.0.1:8000 -H "Host: evil.com"should return a 404 (Not Found) status code and page