Use hash_equals() to compare CSRF tokens

This commit is contained in:
Giuseppe Criscione 2024-05-15 22:26:17 +02:00
parent 6dcf2dd03d
commit 1f70e905a2
2 changed files with 5 additions and 23 deletions

View File

@ -3,8 +3,6 @@
namespace Formwork\Security;
use Formwork\Http\Request;
use Formwork\Utils\Session;
use RuntimeException;
class CsrfToken
{
@ -13,11 +11,6 @@ class CsrfToken
*/
protected const SESSION_KEY = 'CSRF_TOKEN';
/**
* Input name to retrieve the CSRF token
*/
protected const INPUT_NAME = 'csrf-token';
public function __construct(protected Request $request)
{
}
@ -43,19 +36,9 @@ class CsrfToken
/**
* Check if given CSRF token is valid
*/
public function validate(?string $token = null): bool
public function validate(string $token): bool
{
if ($token === null) {
$postData = $this->request->input();
$valid = $postData->has(self::INPUT_NAME) && $this->get() === $postData->get(self::INPUT_NAME);
} else {
$valid = $this->get() === $token;
}
if (!$valid) {
$this->destroy();
throw new RuntimeException('CSRF token not valid');
}
return $valid;
return ($storedToken = $this->get()) && hash_equals($token, $storedToken);
}
/**

View File

@ -243,10 +243,9 @@ return [
'request.validateCsrf' => [
'action' => static function (Request $request, Translations $translations, Panel $panel, CsrfToken $csrfToken) {
// Validate CSRF token
try {
$csrfToken->validate();
} catch (RuntimeException) {
$token = $request->input()->get('csrf-token');
if (!($token !== null && $csrfToken->validate($token))) {
$csrfToken->destroy();
$request->session()->remove('FORMWORK_USERNAME');