Add cms.enableXsrfCookies config value (default true) to configure whether or not the XSRF cookie is automatically sent or if CSRF tokens are solely relied on.

Related: https://github.com/octobercms/october/pull/4701#issuecomment-547773385 & https://github.com/laravel/framework/pull/24726
This commit is contained in:
Luke Towers 2019-10-30 08:08:54 -06:00
parent 457466c5af
commit 959b85f56c
2 changed files with 32 additions and 11 deletions

View File

@ -374,13 +374,26 @@ return [
| Cross Site Request Forgery (CSRF) Protection | Cross Site Request Forgery (CSRF) Protection
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| |
| If the CSRF protection is enabled, all "postback" requests are checked | If the CSRF protection is enabled, all "postback" & AJAX requests are
| for a valid security token. | checked for a valid security token.
| |
*/ */
'enableCsrfProtection' => true, 'enableCsrfProtection' => true,
/*
|--------------------------------------------------------------------------
| Automatic XSRF Cookies
|--------------------------------------------------------------------------
|
| Automatically provide and process an XSRF cookie to the browser to
| support CSRF protection on all AJAX requests without having to add
| an explicit CSRF token to the frontend markup
|
*/
'enableXsrfCookies' => true,
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Force bytecode invalidation | Force bytecode invalidation

View File

@ -29,6 +29,7 @@ use October\Rain\Exception\ValidationException;
use October\Rain\Parse\Bracket as TextParser; use October\Rain\Parse\Bracket as TextParser;
use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\Cookie;
use Illuminate\Http\RedirectResponse; use Illuminate\Http\RedirectResponse;
use Symfony\Component\HttpFoundation\Response as BaseResponse;
/** /**
* The CMS controller class. * The CMS controller class.
@ -124,7 +125,7 @@ class Controller
throw new CmsException(Lang::get('cms::lang.theme.active.not_found')); throw new CmsException(Lang::get('cms::lang.theme.active.not_found'));
} }
$this->assetPath = Config::get('cms.themesPath', '/themes').'/'.$this->theme->getDirName(); $this->assetPath = Config::get('cms.themesPath', '/themes') . '/' . $this->theme->getDirName();
$this->router = new Router($this->theme); $this->router = new Router($this->theme);
$this->partialStack = new PartialStack; $this->partialStack = new PartialStack;
$this->initTwigEnvironment(); $this->initTwigEnvironment();
@ -136,16 +137,21 @@ class Controller
* Finds and serves the requested page. * Finds and serves the requested page.
* If the page cannot be found, returns the page with the URL /404. * If the page cannot be found, returns the page with the URL /404.
* If the /404 page doesn't exist, returns the system 404 page. * If the /404 page doesn't exist, returns the system 404 page.
* * If the parameter is omitted, the current URL used. * If the parameter is null, the current URL used. If it is not
* provided then '/' is used
* *
* @param string $url Specifies the requested page URL. * @param string|null $url Specifies the requested page URL.
* @return Response Returns the processed page content. * @return BaseResponse Returns the response to the provided URL
*/ */
public function run($url = '/') public function run($url = '/')
{ {
$response = $this->runInternal($url); $response = $this->runInternal($url);
if (Config::get('cms.enableCsrfProtection') && $response instanceof \Symfony\Component\HttpFoundation\Response) { if (
Config::get('cms.enableCsrfProtection', true) &&
Config::get('cms.enableXsrfCookies', true) &&
$response instanceof BaseResponse
) {
$this->addXsrfCookie($response); $this->addXsrfCookie($response);
} }
@ -156,7 +162,7 @@ class Controller
* Process the request internally * Process the request internally
* *
* @param string $url Specifies the requested page URL. * @param string $url Specifies the requested page URL.
* @return Response Returns the processed page content. * @return BaseResponse Returns the response to the provided URL
*/ */
protected function runInternal($url = '/') protected function runInternal($url = '/')
{ {
@ -1607,9 +1613,11 @@ class Controller
/** /**
* Adds anti-CSRF cookie. * Adds anti-CSRF cookie.
* Adds a cookie with a token for CSRF checks to the response. * Adds a cookie with a token for CSRF checks to the response.
* @return Response *
* @param BaseResponse $response The response object to add the cookie to
* @return BaseResponse
*/ */
protected function addXsrfCookie(\Symfony\Component\HttpFoundation\Response $response) protected function addXsrfCookie(BaseResponse $response)
{ {
$config = Config::get('session'); $config = Config::get('session');
@ -1638,7 +1646,7 @@ class Controller
*/ */
protected function verifyCsrfToken() protected function verifyCsrfToken()
{ {
if (!Config::get('cms.enableCsrfProtection')) { if (!Config::get('cms.enableCsrfProtection', true)) {
return true; return true;
} }