From 4a6e0e1e0e2c3facebc17e0db38c5b4d4cb05bd0 Mon Sep 17 00:00:00 2001 From: Samuel Georges Date: Mon, 30 Oct 2017 08:59:19 +1100 Subject: [PATCH] Implement CSRF token by default Implement CSRF protection on CMS for postback handling --- config/cms.php | 2 +- modules/cms/classes/Controller.php | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/config/cms.php b/config/cms.php index e6f7c32b9..5c35ca4f3 100644 --- a/config/cms.php +++ b/config/cms.php @@ -332,7 +332,7 @@ return [ | */ - 'enableCsrfProtection' => false, + 'enableCsrfProtection' => true, /* |-------------------------------------------------------------------------- diff --git a/modules/cms/classes/Controller.php b/modules/cms/classes/Controller.php index b2b7852c6..971da3f41 100644 --- a/modules/cms/classes/Controller.php +++ b/modules/cms/classes/Controller.php @@ -337,6 +337,7 @@ class Controller if ( $useAjax && ($handler = post('_handler')) && + ($this->verifyCsrfToken()) && ($handlerResponse = $this->runAjaxHandler($handler)) && $handlerResponse !== true ) { @@ -1355,4 +1356,32 @@ class Controller } } } + + // + // Security + // + + /** + * Checks the request data / headers for a valid CSRF token. + * Returns false if a valid token is not found. Override this + * method to disable the check. + * @return bool + */ + protected function verifyCsrfToken() + { + if (!Config::get('cms.enableCsrfProtection')) { + return true; + } + + if (in_array(Request::method(), ['HEAD', 'GET', 'OPTIONS'])) { + return true; + } + + $token = Request::input('_token') ?: Request::header('X-CSRF-TOKEN'); + + return hash_equals( + Session::token(), + $token + ); + } }