Adds CSRF protection to the backend - Refs #105

This commit is contained in:
Samuel Georges 2015-06-20 21:17:58 +10:00
parent 9cce76c574
commit d9dfa21372
4 changed files with 51 additions and 0 deletions

View File

@ -2,6 +2,18 @@
* October General Utilities
*/
/*
* Ensure the CSRF token is added to all AJAX requests.
*/
$.ajaxPrefilter(function(options) {
var token = $('meta[name="csrf-token"]').attr('content')
if (token) {
options.headers['X-CSRF-TOKEN'] = token
}
})
/*
* Implement "Sweet Alert" with AJAX framework
*/

View File

@ -118,6 +118,11 @@ class Controller extends Extendable
*/
protected $statusCode = 200;
/**
* @var bool Determine if submission requests use CSRF protection.
*/
public $useSecurityToken = true;
/**
* Constructor.
*/
@ -168,6 +173,13 @@ class Controller extends Extendable
$this->action = $action;
$this->params = $params;
/*
* Check security token.
*/
if ($this->useSecurityToken && !$this->verifyCsrfToken()) {
return Response::make(Lang::get('backend::lang.page.invalid_token.label'), 403);
}
/*
* Extensibility
*/
@ -596,4 +608,27 @@ class Controller extends Extendable
$hiddenHints = UserPreferences::forUser()->get('backend::hints.hidden', []);
return array_key_exists($name, $hiddenHints);
}
//
// CSRF Protection
//
/**
* Checks the request data / headers for a valid CSRF token.
* Returns false if a valid token is not found.
* @return bool
*/
protected function verifyCsrfToken()
{
if (in_array(Request::method(), ['HEAD', 'GET', 'OPTIONS'])) {
return true;
}
$token = Request::input('_token') ?: Request::header('X-CSRF-TOKEN');
return \Symfony\Component\Security\Core\Util\StringUtils::equals(
Session::getToken(),
$token
);
}
}

View File

@ -18,6 +18,9 @@ return [
'label' => 'Access denied',
'help' => "You don't have the required permissions to view this page.",
'cms_link' => 'Return to the back-end'
],
'invalid_token' => [
'label' => 'Invalid security token'
]
],
'partial' => [

View File

@ -2,6 +2,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=0, minimal-ui">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="backend-base-path" content="<?= Backend::baseUrl() ?>">
<meta name="csrf-token" content="<?= csrf_token() ?>">
<link rel="icon" type="image/png" href="<?= Backend::skinAsset('assets/images/favicon.png') ?>">
<title data-title-template="<?= empty($this->pageTitleTemplate) ? '%s' : e($this->pageTitleTemplate) ?> | <?= e(Backend\Models\BrandSettings::get('app_name')) ?>">
<?= e(trans($this->pageTitle)) ?> | <?= e(Backend\Models\BrandSettings::get('app_name')) ?>