Skip to content

Commit

Permalink
Dont serialize or unserialize csrf cookie / header
Browse files Browse the repository at this point in the history
Reference:
laravel#25121
laravel@9725a8e

由於 Laravel 5.1 上游已經沒有再 maintain 了,短時間要升級上去有點困難
故自己將這個 patch 上去,自己來 maintain 這個 5.1 的 security issue

hard code `XSRF-TOKEN` 不進行 serialize or unserialize 動作
  • Loading branch information
hashman committed Mar 25, 2019
1 parent e32e927 commit 1ac5934
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 12 deletions.
6 changes: 4 additions & 2 deletions src/Illuminate/Contracts/Encryption/Encrypter.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@ interface Encrypter
* Encrypt the given value.
*
* @param string $value
* @param bool $serialize
* @return string
*/
public function encrypt($value);
public function encrypt($value, $serialize = true);

/**
* Decrypt the given value.
*
* @param string $payload
* @param bool $unserialize
* @return string
*/
public function decrypt($payload);
public function decrypt($payload, $unserialize = false);
}
22 changes: 17 additions & 5 deletions src/Illuminate/Cookie/Middleware/EncryptCookies.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ class EncryptCookies
*/
protected $except = [];

/**
* The cookies that should not be serialized.
*
* @var array
*/
protected $serialization = [
'XSRF-TOKEN' => false,
];

/**
* Create a new CookieGuard instance.
*
Expand Down Expand Up @@ -73,7 +82,7 @@ protected function decrypt(Request $request)
}

try {
$request->cookies->set($key, $this->decryptCookie($c));
$request->cookies->set($key, $this->decryptCookie($key, $c));
} catch (DecryptException $e) {
$request->cookies->set($key, null);
}
Expand All @@ -85,14 +94,15 @@ protected function decrypt(Request $request)
/**
* Decrypt the given cookie and return the value.
*
* @param string $name
* @param string|array $cookie
* @return string|array
*/
protected function decryptCookie($cookie)
protected function decryptCookie($name, $cookie)
{
return is_array($cookie)
? $this->decryptArray($cookie)
: $this->encrypter->decrypt($cookie);
: $this->encrypter->decrypt($cookie, $this->serialization[$name] ?? true);
}

/**
Expand All @@ -107,7 +117,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, $this->serialization[$key] ?? true);
}
}

Expand All @@ -127,8 +137,10 @@ protected function encrypt(Response $response)
continue;
}

$serialize = $this->serialization[$cookie->getName()] ?? true;

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

Expand Down
13 changes: 9 additions & 4 deletions src/Illuminate/Encryption/Encrypter.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,19 @@ public static function supported($key, $cipher)
* Encrypt the given value.
*
* @param string $value
* @param bool $serialize
* @return string
*
* @throws \Illuminate\Contracts\Encryption\EncryptException
*/
public function encrypt($value)
public function encrypt($value, $serialize = true)
{
$iv = Str::randomBytes($this->getIvSize());

$value = \openssl_encrypt(serialize($value), $this->cipher, $this->key, 0, $iv);
$value = \openssl_encrypt(
$serialize ? serialize($value) : $value,
$this->cipher, $this->key, 0, $iv
);

if ($value === false) {
throw new EncryptException('Could not encrypt the data.');
Expand All @@ -88,11 +92,12 @@ public function encrypt($value)
* Decrypt the given value.
*
* @param string $payload
* @param bool $unserialize
* @return string
*
* @throws \Illuminate\Contracts\Encryption\DecryptException
*/
public function decrypt($payload)
public function decrypt($payload, $unserialize = true)
{
$payload = $this->getJsonPayload($payload);

Expand All @@ -104,7 +109,7 @@ public function decrypt($payload)
throw new DecryptException('Could not decrypt the data.');
}

return unserialize($decrypted);
return $unserialize ? unserialize($decrypted) : $decrypted;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ protected function tokensMatch($request)
$token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');

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

if (! is_string($sessionToken) || ! is_string($token)) {
Expand Down

0 comments on commit 1ac5934

Please sign in to comment.