Files
CHIEFSOFT\ameye df3a033196 first commit
2024-06-08 17:09:23 -04:00

97 lines
2.5 KiB
PHP

<?php
/**
* @file classes/security/authorization/internal/ApiCsrfMiddleware.php
*
* Copyright (c) 2014-2021 Simon Fraser University
* Copyright (c) 2000-2021 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class ApiCsrfMiddleware
*
* @ingroup security_authorization
*
* @brief Slim middleware which requires a CSRF token for POST, PUT and DELETE
* operations whenever an API Token is not in use.
*/
namespace PKP\security\authorization\internal;
use APP\core\Application;
use PKP\core\APIResponse;
use PKP\handler\APIHandler;
use Slim\Http\Request as SlimRequest;
class ApiCsrfMiddleware
{
/** @var APIHandler $handler Reference to api handler */
protected $_handler = null;
/**
* Constructor
*
*/
public function __construct(APIHandler $handler)
{
$this->_handler = $handler;
}
/**
* Middleware invokable function
*
* @param SlimRequest $slimRequest request
* @param APIResponse $response response
* @param callable $next Next middleware
*
* @return APIResponse
*/
public function __invoke($slimRequest, $response, $next)
{
if ($this->_isCSRFRequired($slimRequest) && !$this->_isCSRFValid($slimRequest)) {
return $response->withJson([
'error' => 'form.csrfInvalid',
'errorMessage' => __('form.csrfInvalid'),
], 403);
}
$response = $next($slimRequest, $response);
return $response;
}
/**
* Check if a CSRF token is required
*
* @param SlimRequest $slimRequest
*
* @return bool
*/
protected function _isCSRFRequired($slimRequest)
{
if ($this->_handler->getApiToken()) {
return false;
}
$server = $slimRequest->getServerParams();
return !empty($server['REQUEST_METHOD']) && in_array($server['REQUEST_METHOD'], ['POST', 'PUT', 'DELETE']);
}
/**
* Check if the CSRF token is present and valid
*
* @param SlimRequest $slimRequest
*
* @return bool
*/
protected function _isCSRFValid($slimRequest)
{
$server = $slimRequest->getServerParams();
if (empty($server['HTTP_X_CSRF_TOKEN'])) {
return false;
}
$session = Application::get()->getRequest()->getSession();
return $session && $session->getCSRFToken() === $server['HTTP_X_CSRF_TOKEN'];
}
}
if (!PKP_STRICT_MODE) {
class_alias('\PKP\security\authorization\internal\ApiCsrfMiddleware', '\ApiCsrfMiddleware');
}