Skip to content

Commit

Permalink
Fix Cookie serialization vulnerability in laravel/framework
Browse files Browse the repository at this point in the history
  • Loading branch information
freescout-help-desk committed Sep 22, 2023
1 parent 21d8632 commit 8363650
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 3 deletions.
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
"Codedge\\Updater\\SourceRepositoryTypes\\": "overrides/codedge/laravel-selfupdater/src/SourceRepositoryTypes/",
"Barryvdh\\TranslationManager\\": "overrides/barryvdh/laravel-translation-manager/src/",
"Illuminate\\Foundation\\": "overrides/laravel/framework/src/Illuminate/Foundation/",
"Illuminate\\Foundation\\Http\\Middleware\\": "overrides/laravel/framework/src/Illuminate/Foundation/Http/Middleware/",
"Illuminate\\Routing\\": "overrides/laravel/framework/src/Illuminate/Routing/",
"Illuminate\\Broadcasting\\Broadcasters\\": "overrides/laravel/framework/src/Illuminate/Broadcasting/Broadcasters/",
"Illuminate\\Validation\\Concerns\\": "overrides/laravel/framework/src/Illuminate/Validation/Concerns/",
Expand Down Expand Up @@ -188,6 +189,7 @@
"vendor/barryvdh/laravel-translation-manager/src/Controller.php",
"vendor/laravel/framework/src/Illuminate/Foundation/ProviderRepository.php",
"vendor/laravel/framework/src/Illuminate/Foundation/PackageManifest.php",
"vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php",
"vendor/laravel/framework/src/Illuminate/Routing/UrlGenerator.php",
"vendor/laravel/framework/src/Illuminate/Routing/RouteSignatureParameters.php",
"vendor/laravel/framework/src/Illuminate/Routing/RouteDependencyResolverTrait.php",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ protected function decryptCookie($cookie)
{
return is_array($cookie)
? $this->decryptArray($cookie)
: $this->encrypter->decrypt($cookie);
: $this->encrypter->decrypt($cookie, false);
}

/**
Expand All @@ -118,7 +118,7 @@ protected function decryptArray(array $cookie)

foreach ($cookie as $key => $value) {
if (is_string($value)) {
$decrypted[$key] = $this->encrypter->decrypt($value);
$decrypted[$key] = $this->encrypter->decrypt($value, false);
}
}

Expand All @@ -145,7 +145,7 @@ protected function encrypt(Response $response)
}

$response->headers->setCookie($this->duplicate(
$cookie, $this->encrypter->encrypt($prefix.$cookie->getValue())
$cookie, $this->encrypter->encrypt($prefix.$cookie->getValue(), false)
));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
<?php

namespace Illuminate\Foundation\Http\Middleware;

use Closure;
use Illuminate\Foundation\Application;
use Illuminate\Support\InteractsWithTime;
use Symfony\Component\HttpFoundation\Cookie;
use Illuminate\Contracts\Encryption\Encrypter;
use Illuminate\Session\TokenMismatchException;

class VerifyCsrfToken
{
use InteractsWithTime;

/**
* The application instance.
*
* @var \Illuminate\Foundation\Application
*/
protected $app;

/**
* The encrypter implementation.
*
* @var \Illuminate\Contracts\Encryption\Encrypter
*/
protected $encrypter;

/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [];

/**
* Create a new middleware instance.
*
* @param \Illuminate\Foundation\Application $app
* @param \Illuminate\Contracts\Encryption\Encrypter $encrypter
* @return void
*/
public function __construct(Application $app, Encrypter $encrypter)
{
$this->app = $app;
$this->encrypter = $encrypter;
}

/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*
* @throws \Illuminate\Session\TokenMismatchException
*/
public function handle($request, Closure $next)
{
if (
$this->isReading($request) ||
$this->runningUnitTests() ||
$this->inExceptArray($request) ||
$this->tokensMatch($request)
) {
return $this->addCookieToResponse($request, $next($request));
}

throw new TokenMismatchException;
}

/**
* Determine if the HTTP request uses a ‘read’ verb.
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
protected function isReading($request)
{
return in_array($request->method(), ['HEAD', 'GET', 'OPTIONS']);
}

/**
* Determine if the application is running unit tests.
*
* @return bool
*/
protected function runningUnitTests()
{
return $this->app->runningInConsole() && $this->app->runningUnitTests();
}

/**
* Determine if the request has a URI that should pass through CSRF verification.
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
protected function inExceptArray($request)
{
foreach ($this->except as $except) {
if ($except !== '/') {
$except = trim($except, '/');
}

if ($request->fullUrlIs($except) || $request->is($except)) {
return true;
}
}

return false;
}

/**
* Determine if the session and input CSRF tokens match.
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
protected function tokensMatch($request)
{
$token = $this->getTokenFromRequest($request);

return is_string($request->session()->token()) &&
is_string($token) &&
hash_equals($request->session()->token(), $token);
}

/**
* Get the CSRF token from the request.
*
* @param \Illuminate\Http\Request $request
* @return string
*/
protected function getTokenFromRequest($request)
{
$token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');

if (! $token && $header = $request->header('X-XSRF-TOKEN')) {
$token = $this->encrypter->decrypt($header, false);
}

return $token;
}

/**
* Add the CSRF token to the response cookies.
*
* @param \Illuminate\Http\Request $request
* @param \Symfony\Component\HttpFoundation\Response $response
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function addCookieToResponse($request, $response)
{
$config = config('session');

$response->headers->setCookie(
new Cookie(
'XSRF-TOKEN', $request->session()->token(), $this->availableAt(60 * $config['lifetime']),
$config['path'], $config['domain'], $config['secure'], false, false, $config['same_site'] ?? null
)
);

return $response;
}
}

0 comments on commit 8363650

Please sign in to comment.