first commit
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
<?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');
|
||||
}
|
||||
Reference in New Issue
Block a user