mirror of
https://github.com/linuxserver/Heimdall.git
synced 2026-08-07 07:16:13 +00:00
Enforce TRUSTED_HOSTS allow-list regardless of APP_ENV
The custom TrustHosts middleware only overrode hosts(), so it inherited the parent's shouldSpecifyTrustedHosts() gate, which skips enforcement whenever the app runs in the local environment or under the test runner. Heimdall ships APP_ENV=local by default (.env.example, copied to .env on install), so the TRUSTED_HOSTS allow-list a user configures per the .env.example guidance was never actually applied. Override shouldSpecifyTrustedHosts() to tie enforcement to configuration instead of environment: apply the allow-list whenever TRUSTED_HOSTS is set, in any environment; when it is unset hosts() is empty and enforcement stays off, preserving the historic no-restriction behaviour. Add handle()-driven tests covering both the configured and unconfigured cases.
This commit is contained in:
@@ -38,4 +38,23 @@ class TrustHosts extends Middleware
|
|||||||
|
|
||||||
return $hosts;
|
return $hosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the application should specify trusted hosts.
|
||||||
|
*
|
||||||
|
* The parent implementation skips enforcement whenever the app runs in the
|
||||||
|
* "local" environment (Heimdall's shipped default, see .env.example) or
|
||||||
|
* under the test runner, which would leave the TRUSTED_HOSTS allow-list
|
||||||
|
* silently unenforced for almost every real deployment. Instead we tie
|
||||||
|
* enforcement directly to configuration: apply the allow-list whenever one
|
||||||
|
* has actually been provided, in any environment. When TRUSTED_HOSTS is
|
||||||
|
* unset hosts() is empty and this returns false, preserving the historic
|
||||||
|
* no-restriction behaviour.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function shouldSpecifyTrustedHosts()
|
||||||
|
{
|
||||||
|
return ! empty($this->hosts());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,4 +105,42 @@ class TrustHostsTest extends TestCase
|
|||||||
$this->assertContains(TrustHosts::class, $globalMiddleware);
|
$this->assertContains(TrustHosts::class, $globalMiddleware);
|
||||||
$this->assertNotContains(\Illuminate\Http\Middleware\TrustHosts::class, $globalMiddleware);
|
$this->assertNotContains(\Illuminate\Http\Middleware\TrustHosts::class, $globalMiddleware);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_handle_enforces_trusted_hosts_even_in_local_environment(): void
|
||||||
|
{
|
||||||
|
// The app runs as APP_ENV=local under the test runner; the parent
|
||||||
|
// middleware would skip enforcement entirely. Confirm handle() still
|
||||||
|
// applies the allow-list once TRUSTED_HOSTS is configured.
|
||||||
|
$this->setTrustedHostsEnv('example.com');
|
||||||
|
|
||||||
|
$request = Request::create('http://example.com/', 'GET');
|
||||||
|
|
||||||
|
$reachedNext = false;
|
||||||
|
$this->makeMiddleware()->handle($request, function ($req) use (&$reachedNext) {
|
||||||
|
$reachedNext = true;
|
||||||
|
|
||||||
|
return $req;
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->assertTrue($reachedNext);
|
||||||
|
|
||||||
|
// The configured host is now accepted and any other Host is rejected.
|
||||||
|
$this->assertSame('example.com', Request::create('http://example.com/', 'GET')->getHost());
|
||||||
|
|
||||||
|
$this->expectException(SuspiciousOperationException::class);
|
||||||
|
Request::create('http://evil.com/', 'GET')->getHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_handle_does_not_restrict_hosts_when_env_unset(): void
|
||||||
|
{
|
||||||
|
putenv('TRUSTED_HOSTS');
|
||||||
|
unset($_ENV['TRUSTED_HOSTS'], $_SERVER['TRUSTED_HOSTS']);
|
||||||
|
|
||||||
|
$request = Request::create('http://anything.example/', 'GET');
|
||||||
|
|
||||||
|
$this->makeMiddleware()->handle($request, fn ($req) => $req);
|
||||||
|
|
||||||
|
// No allow-list configured -> arbitrary hosts still accepted.
|
||||||
|
$this->assertSame('anything.example', Request::create('http://anything.example/', 'GET')->getHost());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user