You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
1.9 KiB
76 lines
1.9 KiB
<?php declare(strict_types=1);
|
|
|
|
namespace BradyMcD\TAATP\AntiCSRF;
|
|
use BradyMcD\TAATP\AntiCSRFInterface;
|
|
use BradyMcD\TAATP\SessionInterface;
|
|
|
|
class Base implements AntiCSRFInterface
|
|
{
|
|
const CSRF_TOKEN_IDX = "antiCSRF";
|
|
const CSRF_EXPIRY_IDX = "antiCSRF_Expiry";
|
|
|
|
private string $token;
|
|
|
|
public function __construct(
|
|
private SessionInterface $session,
|
|
private \Psr\Clock\ClockInterface $clock
|
|
)
|
|
{
|
|
assert($session->live(), "A live session is required to match anti-CSRF tokens across requests.");
|
|
$this->generate();
|
|
}
|
|
|
|
/** @SuppressWarnings(PHPMD.Superglobals) */
|
|
public function match(): bool
|
|
{
|
|
$request_token = $_REQUEST[self::CSRF_TOKEN_IDX] ?? false;
|
|
|
|
if ($request_token && \hash_equals($this->token, $request_token))
|
|
{
|
|
return !$this->expired();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public function expired(): bool
|
|
{
|
|
return $this->clock->now()->getTimestamp() >= $this->session->get(self::CSRF_EXPIRY_IDX);
|
|
}
|
|
|
|
public function emitStr(): string
|
|
{
|
|
return
|
|
'<input type="hidden" name="'
|
|
. self::CSRF_TOKEN_IDX
|
|
. '" value="'
|
|
. $this->token
|
|
. '" />';
|
|
}
|
|
|
|
public function display()
|
|
{
|
|
echo $this->emitStr();
|
|
}
|
|
|
|
private function expiry(): int
|
|
{
|
|
return $this->clock->now()->getTimestamp() + 3600;
|
|
}
|
|
|
|
public function generate()
|
|
{
|
|
$this->session->tryStore(self::CSRF_TOKEN_IDX, \bin2hex(\random_bytes(32)));
|
|
$this->token = $this->session->get(self::CSRF_TOKEN_IDX);
|
|
$this->session->tryStore(self::CSRF_EXPIRY_IDX, $this->expiry());
|
|
}
|
|
|
|
public function regenerate()
|
|
{
|
|
$this->session->store(self::CSRF_TOKEN_IDX, \bin2hex(\random_bytes(32)));
|
|
$this->token = $this->session->get(self::CSRF_TOKEN_IDX);
|
|
$this->session->store(self::CSRF_EXPIRY_IDX, $this->expiry());
|
|
}
|
|
}
|
|
|
|
?>
|