diff --git a/config/cms.php b/config/cms.php index 0c704765c..a56d7b2b0 100644 --- a/config/cms.php +++ b/config/cms.php @@ -38,6 +38,19 @@ return [ 'backendUri' => 'backend', + /* + |-------------------------------------------------------------------------- + | Back-end force HTTPS security + |-------------------------------------------------------------------------- + | + | Use this setting to force a secure protocol when accessing any back-end + | pages, including the authentication pages. If set to null, this setting + | is enabled when debug mode (app.debug) is disabled. + | + */ + + 'backendForceSecure' => null, + /* |-------------------------------------------------------------------------- | Back-end timezone @@ -284,8 +297,8 @@ return [ |-------------------------------------------------------------------------- | | If safe mode is enabled, the PHP code section is disabled in the CMS - | for security reasons. If set to null, safe mode is on when debug mode - | (app.debug) is disabled. + | for security reasons. If set to null, safe mode is enabled when + | debug mode (app.debug) is disabled. | */ diff --git a/modules/backend/classes/Controller.php b/modules/backend/classes/Controller.php index f29a5ed85..051ad5ad5 100644 --- a/modules/backend/classes/Controller.php +++ b/modules/backend/classes/Controller.php @@ -9,6 +9,7 @@ use Config; use Request; use Backend; use Session; +use Redirect; use Response; use Exception; use BackendAuth; @@ -174,6 +175,13 @@ class Controller extends Extendable return Response::make(Lang::get('backend::lang.page.invalid_token.label'), 403); } + /* + * Check forced HTTPS protocol. + */ + if (!$this->verifyForceSecure()) { + return Redirect::secure(Request::path()); + } + /* * Extensibility */ @@ -667,7 +675,7 @@ class Controller extends Extendable } // - // CSRF Protection + // Security // /** @@ -693,4 +701,23 @@ class Controller extends Extendable $token ); } + + /** + * Checks if the back-end should force a secure protocol (HTTPS) enabled by config. + * @return bool + */ + protected function verifyForceSecure() + { + if (Request::secure() || Request::ajax()) { + return true; + } + + // @todo if year >= 2018 change default from false to null + $forceSecure = Config::get('cms.backendForceSecure', false); + if ($forceSecure === null) { + $forceSecure = !Config::get('app.debug', false); + } + + return !$forceSecure; + } } diff --git a/modules/system/classes/ErrorHandler.php b/modules/system/classes/ErrorHandler.php index 6a919b96f..282a50c28 100644 --- a/modules/system/classes/ErrorHandler.php +++ b/modules/system/classes/ErrorHandler.php @@ -53,13 +53,14 @@ class ErrorHandler extends ErrorHandlerBase */ public function handleCustomError() { - if (Config::get('app.debug', false)) + if (Config::get('app.debug', false)) { return null; + } $theme = Theme::getActiveTheme(); + $router = new Router($theme); // Use the default view if no "/error" URL is found. - $router = new Router($theme); if (!$router->findByUrl('/error')) { return View::make('cms::error'); }