. */ namespace SP\Core\Crypt; use SP\Config\ConfigData; use SP\Core\Context\ContextInterface; use SP\Core\Context\SessionContext; use SP\Http\Request; /** * Class CSRF * * @package SP\Core\Crypt */ final class CSRF { /** * @var SessionContext */ private $context; /** * @var Request */ private $request; /** * @var ConfigData */ private $configData; /** * CSRF constructor. * * @param ContextInterface $context * @param Request $request * @param ConfigData $configData */ public function __construct(ContextInterface $context, Request $request, ConfigData $configData) { $this->context = $context; $this->request = $request; $this->configData = $configData; } /** * Check for CSRF token on POST requests */ public function check(): bool { $method = strtoupper($this->request->getMethod()); $with = $this->request->getHeader('X-Requested-With'); if ($this->context->isLoggedIn() && $this->context->getCSRF() !== null && ($method === 'POST' || ($method === 'GET' && $with === 'XMLHttpRequest')) ) { $token = $this->request->getHeader('X-CSRF'); if (empty($token) || !Hash::checkMessage($this->getKey(), $this->configData->getPasswordSalt(), $token) ) { logger(sprintf('Invalid CSRF token: %s', $token), 'ERROR'); return false; } logger('CSRF token OK'); } return true; } /** * Devolver la llave de cifrado para los datos de la cookie * * @return string */ private function getKey(): string { return sha1($this->request->getHeader('User-Agent') . $this->request->getClientAddress()); } /** * Initialize the CSRF key * * @return void */ public function initialize() { if ($this->context->isLoggedIn() && $this->context->getCSRF() === null ) { $key = Hash::signMessage($this->getKey(), $this->configData->getPasswordSalt()); $this->context->setCSRF($key); logger(sprintf('CSRF key (set): %s', $this->context->getCSRF())); } } }