- trustHosts erlaubt nur die konfigurierten Domains (plus localhost/IP für Health-Checks) und verwirft fremde Host-Header, sodass X-Forwarded-Host keine URL-Generierung mehr vergiften kann (H5). - Legacy-API-Keys nur noch per Header (Bearer/X-ApiKey); die alte Query-/Body-Übergabe wird nicht mehr zur Auth akzeptiert, erhält aber weiterhin den 410-Migrationshinweis statt eines opaken 401 (M11). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
45 lines
1.6 KiB
PHP
45 lines
1.6 KiB
PHP
<?php
|
|
|
|
use Illuminate\Http\Middleware\TrustHosts;
|
|
use Tests\TestCase;
|
|
|
|
/**
|
|
* Sichert die Host-Whitelist (H5-Fix) ab: konfigurierte Domains und lokale
|
|
* Health-Check-Hosts sind zulässig, fremde Hosts werden abgewiesen. Da Laravel
|
|
* die Erzwingung in Unit-Tests überspringt, prüfen wir die Pattern-Liste selbst.
|
|
*/
|
|
function trustedHostMatches(string $host): bool
|
|
{
|
|
/** @var array<int, string> $patterns */
|
|
$patterns = app(TrustHosts::class)->hosts();
|
|
|
|
foreach (array_filter($patterns) as $pattern) {
|
|
if (preg_match('#'.$pattern.'#i', $host) === 1) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
test('configured domains and their subdomains are trusted', function () {
|
|
/** @var TestCase $this */
|
|
expect(trustedHostMatches(config('domains.domain_portal')))->toBeTrue();
|
|
expect(trustedHostMatches(config('domains.domain_presseecho')))->toBeTrue();
|
|
expect(trustedHostMatches(config('domains.domain_businessportal')))->toBeTrue();
|
|
expect(trustedHostMatches('www.'.config('domains.domain_portal')))->toBeTrue();
|
|
});
|
|
|
|
test('local health check hosts are trusted', function () {
|
|
/** @var TestCase $this */
|
|
expect(trustedHostMatches('localhost'))->toBeTrue();
|
|
expect(trustedHostMatches('127.0.0.1'))->toBeTrue();
|
|
expect(trustedHostMatches('10.0.5.12'))->toBeTrue();
|
|
});
|
|
|
|
test('foreign hosts are rejected', function () {
|
|
/** @var TestCase $this */
|
|
expect(trustedHostMatches('evil.com'))->toBeFalse();
|
|
expect(trustedHostMatches('pressekonto.test.evil.com'))->toBeFalse();
|
|
expect(trustedHostMatches('notlocalhost'))->toBeFalse();
|
|
});
|