Skip to content

Commit

Permalink
[11.x] Fix Middleware::trustHosts(subdomains: true) (#50877)
Browse files Browse the repository at this point in the history
* Fix usage of config before its resolved

* Allow trusting hosts via a callback

* Remove unused import

* Update TrustHosts.php

---------

Co-authored-by: Taylor Otwell <taylor@laravel.com>
  • Loading branch information
axlon and taylorotwell authored Apr 1, 2024
1 parent e122d0b commit 2617749
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 20 deletions.
6 changes: 3 additions & 3 deletions src/Illuminate/Foundation/Configuration/Middleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -608,15 +608,15 @@ public function trimStrings(array $except = [])
/**
* Indicate that the trusted host middleware should be enabled.
*
* @param array<int, string>|null $at
* @param array<int, string>|(callable(): array<int, string>)|null $at
* @param bool $subdomains
* @return $this
*/
public function trustHosts(array $at = null, bool $subdomains = true)
public function trustHosts(array|callable $at = null, bool $subdomains = true)
{
$this->trustHosts = true;

if (is_array($at)) {
if (! is_null($at)) {
TrustHosts::at($at, $subdomains);
}

Expand Down
39 changes: 27 additions & 12 deletions src/Illuminate/Http/Middleware/TrustHosts.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,17 @@ class TrustHosts
/**
* The trusted hosts that have been configured to always be trusted.
*
* @var array<int, string>|null
* @var array<int, string>|(callable(): array<int, string>)|null
*/
protected static $alwaysTrust;

/**
* Indicates whether subdomains of the application URL should be trusted.
*
* @var bool|null
*/
protected static $subdomains;

/**
* Create a new middleware instance.
*
Expand All @@ -39,9 +46,21 @@ public function __construct(Application $app)
*/
public function hosts()
{
return is_array(static::$alwaysTrust)
? static::$alwaysTrust
: [$this->allSubdomainsOfApplicationUrl()];
if (is_null(static::$alwaysTrust)) {
return [$this->allSubdomainsOfApplicationUrl()];
}

$hosts = match (true) {
is_array(static::$alwaysTrust) => static::$alwaysTrust,
is_callable(static::$alwaysTrust) => call_user_func(static::$alwaysTrust),
default => [],
};

if (static::$subdomains) {
$hosts[] = $this->allSubdomainsOfApplicationUrl();
}

return $hosts;
}

/**
Expand All @@ -63,19 +82,14 @@ public function handle(Request $request, $next)
/**
* Specify the hosts that should always be trusted.
*
* @param array<int, string> $hosts
* @param array<int, string>|(callable(): array<int, string>) $hosts
* @param bool $subdomains
* @return void
*/
public static function at(array $hosts, bool $subdomains = true)
public static function at(array|callable $hosts, bool $subdomains = true)
{
if ($subdomains) {
if ($host = parse_url(config('app.url'), PHP_URL_HOST)) {
$hosts[] = '^(.+\.)?'.preg_quote($host).'$';
}
}

static::$alwaysTrust = $hosts;
static::$subdomains = $subdomains;
}

/**
Expand Down Expand Up @@ -109,5 +123,6 @@ protected function allSubdomainsOfApplicationUrl()
public static function flushState()
{
static::$alwaysTrust = null;
static::$subdomains = null;
}
}
15 changes: 10 additions & 5 deletions tests/Foundation/Configuration/MiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Illuminate\Tests\Foundation\Configuration;

use Illuminate\Config\Repository;
use Illuminate\Container\Container;
use Illuminate\Contracts\Encryption\Encrypter;
use Illuminate\Contracts\Foundation\Application;
Expand Down Expand Up @@ -219,23 +218,29 @@ protected function allSubdomainsOfApplicationUrl()
$configuration->trustHosts();
$this->assertEquals(['^(.+\.)?laravel\.test$'], $middleware->hosts());

app()['config'] = Mockery::mock(Repository::class);
app()['config']->shouldReceive('get')->with('app.url', null)->times(3)->andReturn('http://laravel.test');

$configuration->trustHosts(at: ['my.test']);
$this->assertEquals(['my.test', '^(.+\.)?laravel\.test$'], $middleware->hosts());

$configuration->trustHosts(at: ['my.test']);
$configuration->trustHosts(at: static fn () => ['my.test']);
$this->assertEquals(['my.test', '^(.+\.)?laravel\.test$'], $middleware->hosts());

$configuration->trustHosts(at: ['my.test'], subdomains: false);
$this->assertEquals(['my.test'], $middleware->hosts());

$configuration->trustHosts(at: static fn () => ['my.test'], subdomains: false);
$this->assertEquals(['my.test'], $middleware->hosts());

$configuration->trustHosts(at: []);
$this->assertEquals(['^(.+\.)?laravel\.test$'], $middleware->hosts());

$configuration->trustHosts(at: static fn () => []);
$this->assertEquals(['^(.+\.)?laravel\.test$'], $middleware->hosts());

$configuration->trustHosts(at: [], subdomains: false);
$this->assertEquals([], $middleware->hosts());

$configuration->trustHosts(at: static fn () => [], subdomains: false);
$this->assertEquals([], $middleware->hosts());
}

public function testEncryptCookies()
Expand Down

0 comments on commit 2617749

Please sign in to comment.