Added verification of a token generated outside the engine

https://forkbb.ru/post/211#p211
This commit is contained in:
Visman 2023-07-31 23:54:16 +07:00
parent 68abe1e665
commit 8f2886d210
2 changed files with 26 additions and 9 deletions

View file

@ -20,8 +20,11 @@ class Csrf
protected ?string $error = null;
protected int $hashExpiration = 3600;
public function __construct(protected Secury $secury, #[SensitiveParameter] protected string $key)
{
public function __construct(
protected Secury $secury,
#[SensitiveParameter] protected string $key,
#[SensitiveParameter] protected mixed $externalSalt // сюда и Container может попасть O_o
) {
}
/**
@ -35,12 +38,24 @@ class Csrf
/**
* Возвращает csrf токен
*/
public function create(string $marker, array $args = [], int|string $time = null): string
public function create(string $marker, array $args = [], int|string $time = null, string $type = 's'): string
{
$marker = $this->argsToStr($marker, $args);
$time = $time ?: \time();
return $this->secury->hmac($marker, $time . $this->key) . 's' . $time;
switch ($type) {
case 's':
return $this->secury->hmac($marker, $time . $this->key) . 's' . $time;
case 'x':
if (
\is_string($this->externalSalt)
&& isset($this->externalSalt[9])
) {
return \hash_hmac('sha1', $marker, $time . $this->externalSalt) . 'x' . $time;
}
default:
return 'n';
}
}
/**
@ -85,17 +100,18 @@ class Csrf
if (
\is_string($token)
&& \preg_match('%(e|s)(\d+)$%D', $token, $matches)
&& \preg_match('%(e|s|x)(\d+)$%D', $token, $matches)
) {
switch ($matches[1]) {
// токен
case 's':
case 'x':
if ($matches[2] + ($lifetime ?? self::TOKEN_LIFETIME) < $now) {
// просрочен
$this->error = 'Expired token';
} elseif (
$matches[2] + 0 <= $now
&& \hash_equals($this->create($marker, $args, $matches[2]), $token)
&& \hash_equals($this->create($marker, $args, $matches[2], $matches[1]), $token)
) {
$this->error = null;
$result = true;

View file

@ -181,9 +181,10 @@ return [
'attachments' => \ForkBB\Models\Attachment\Attachments::class,
'Csrf' => [
'class' => \ForkBB\Core\Csrf::class,
'Secury' => '@Secury',
'key' => '%user.password%%user.ip%%user.id%%BASE_URL%',
'class' => \ForkBB\Core\Csrf::class,
'Secury' => '@Secury',
'key' => '%user.password%%user.ip%%user.id%%BASE_URL%',
'extSalt' => '',
],
'Online' => \ForkBB\Models\Online\Online::class,
'Cookie' => [