Import alt-mysql plugin
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
final class CsrfGuard
|
||||
{
|
||||
private string $secret;
|
||||
private string $username;
|
||||
private string $sessionId;
|
||||
|
||||
public function __construct(string $secret, string $username, string $sessionId)
|
||||
{
|
||||
$this->secret = $secret;
|
||||
$this->username = $username;
|
||||
$this->sessionId = $sessionId !== '' ? $sessionId : 'no_session';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{ts:int,token:string}
|
||||
*/
|
||||
public function issue(string $intent): array
|
||||
{
|
||||
$ts = time();
|
||||
$sid = $this->sessionId;
|
||||
return [
|
||||
'ts' => $ts,
|
||||
'sid' => $sid,
|
||||
'token' => $this->buildToken($intent, $ts, $sid),
|
||||
];
|
||||
}
|
||||
|
||||
public function validate(string $intent, string $timestamp, string $token, int $ttl = 3600, string $sessionHint = ''): bool
|
||||
{
|
||||
if (!preg_match('/^[0-9]{1,20}$/', $timestamp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$ts = (int)$timestamp;
|
||||
$now = time();
|
||||
if ($ts <= 0 || $ts > ($now + 30) || ($now - $ts) > $ttl) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$token = trim($token);
|
||||
$sids = [];
|
||||
|
||||
$hint = trim($sessionHint);
|
||||
if ($hint !== '') {
|
||||
$sids[] = $hint;
|
||||
}
|
||||
$sids[] = $this->sessionId;
|
||||
$sids[] = 'no_session';
|
||||
$sids[] = '';
|
||||
$sids = array_values(array_unique($sids));
|
||||
|
||||
foreach ($sids as $sid) {
|
||||
$expected = $this->buildToken($intent, $ts, $sid);
|
||||
if (hash_equals($expected, $token)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function buildToken(string $intent, int $timestamp, string $sid): string
|
||||
{
|
||||
$payload = implode('|', [$this->username, $sid !== '' ? $sid : 'no_session', $intent, (string)$timestamp]);
|
||||
return hash_hmac('sha256', $payload, $this->secret);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user