From acb4b77adc6e257e132e3b036abe1ec88885cfb7 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Tue, 17 Nov 2020 13:39:50 -0600 Subject: [PATCH] Disable CSRF on broadcast route This route does not particularly warrant or require CSRF protection and doing so increases the complication of setting up Laravel Echo in SPA environments. --- src/Illuminate/Broadcasting/BroadcastManager.php | 2 +- .../Broadcasting/Broadcasters/Broadcaster.php | 2 +- .../Broadcasting/Broadcasters/PusherBroadcaster.php | 5 +++-- .../Broadcasting/Broadcasters/RedisBroadcaster.php | 5 +++-- src/Illuminate/Routing/Router.php | 13 ++++++++++++- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/Illuminate/Broadcasting/BroadcastManager.php b/src/Illuminate/Broadcasting/BroadcastManager.php index e3bdb03aaca1..22917d8bc795 100644 --- a/src/Illuminate/Broadcasting/BroadcastManager.php +++ b/src/Illuminate/Broadcasting/BroadcastManager.php @@ -70,7 +70,7 @@ public function routes(array $attributes = null) $router->match( ['get', 'post'], '/broadcasting/auth', '\\'.BroadcastController::class.'@authenticate' - ); + )->withoutMiddleware([\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken::class]); }); } diff --git a/src/Illuminate/Broadcasting/Broadcasters/Broadcaster.php b/src/Illuminate/Broadcasting/Broadcasters/Broadcaster.php index d39258ff5b51..e48b15195741 100644 --- a/src/Illuminate/Broadcasting/Broadcasters/Broadcaster.php +++ b/src/Illuminate/Broadcasting/Broadcasters/Broadcaster.php @@ -317,7 +317,7 @@ protected function retrieveChannelOptions($channel) } /** - * Check if channel name from request match a pattern from registered channels. + * Check if the channel name from the request matches a pattern from registered channels. * * @param string $channel * @param string $pattern diff --git a/src/Illuminate/Broadcasting/Broadcasters/PusherBroadcaster.php b/src/Illuminate/Broadcasting/Broadcasters/PusherBroadcaster.php index 68daf9da4b26..94c95c4501ac 100644 --- a/src/Illuminate/Broadcasting/Broadcasters/PusherBroadcaster.php +++ b/src/Illuminate/Broadcasting/Broadcasters/PusherBroadcaster.php @@ -42,8 +42,9 @@ public function auth($request) { $channelName = $this->normalizeChannelName($request->channel_name); - if ($this->isGuardedChannel($request->channel_name) && - ! $this->retrieveUser($request, $channelName)) { + if (empty($request->channel_name) || + ($this->isGuardedChannel($request->channel_name) && + ! $this->retrieveUser($request, $channelName))) { throw new AccessDeniedHttpException; } diff --git a/src/Illuminate/Broadcasting/Broadcasters/RedisBroadcaster.php b/src/Illuminate/Broadcasting/Broadcasters/RedisBroadcaster.php index 18cb0fef3cdb..2fea183fb6a0 100644 --- a/src/Illuminate/Broadcasting/Broadcasters/RedisBroadcaster.php +++ b/src/Illuminate/Broadcasting/Broadcasters/RedisBroadcaster.php @@ -60,8 +60,9 @@ public function auth($request) str_replace($this->prefix, '', $request->channel_name) ); - if ($this->isGuardedChannel($request->channel_name) && - ! $this->retrieveUser($request, $channelName)) { + if (empty($request->channel_name) || + ($this->isGuardedChannel($request->channel_name) && + ! $this->retrieveUser($request, $channelName))) { throw new AccessDeniedHttpException; } diff --git a/src/Illuminate/Routing/Router.php b/src/Illuminate/Routing/Router.php index c4e4c9fc588e..1828e52105fd 100644 --- a/src/Illuminate/Routing/Router.php +++ b/src/Illuminate/Routing/Router.php @@ -21,6 +21,7 @@ use Illuminate\Support\Traits\Macroable; use JsonSerializable; use Psr\Http\Message\ResponseInterface as PsrResponseInterface; +use ReflectionClass; use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory; use Symfony\Component\HttpFoundation\Response as SymfonyResponse; @@ -708,7 +709,17 @@ public function gatherRouteMiddleware(Route $route) $middleware = collect($route->gatherMiddleware())->map(function ($name) { return (array) MiddlewareNameResolver::resolve($name, $this->middleware, $this->middlewareGroups); })->flatten()->reject(function ($name) use ($excluded) { - return in_array($name, $excluded, true); + if (empty($excluded)) { + return false; + } elseif (in_array($name, $excluded, true)) { + return true; + } + + $reflection = new ReflectionClass($name); + + return collect($excluded)->contains(function ($exclude) use ($reflection) { + return $reflection->isSubclassOf($exclude); + }); })->values(); return $this->sortMiddleware($middleware);