Merge pull request #4731 from octobercms/no_serialize_cookie

No serialize cookie
This commit is contained in:
Samuel Georges 2019-11-02 18:06:27 +11:00 committed by GitHub
commit c0fffc665d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 102 additions and 118 deletions

View File

@ -36,6 +36,7 @@ class Controller extends ControllerBase
use \System\Traits\AssetMaker;
use \System\Traits\ConfigMaker;
use \System\Traits\EventEmitter;
use \System\Traits\SecurityController;
use \Backend\Traits\ErrorMaker;
use \Backend\Traits\WidgetMaker;
use \October\Rain\Extension\ExtendableTrait;
@ -763,55 +764,4 @@ class Controller extends ControllerBase
$hiddenHints = UserPreference::forUser()->get('backend::hints.hidden', []);
return array_key_exists($name, $hiddenHints);
}
//
// 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');
if (!strlen($token) || !strlen(Session::token())) {
return false;
}
return hash_equals(
Session::token(),
$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;
}
}

View File

@ -1172,6 +1172,7 @@ class Lists extends WidgetBase
/**
* Process as text, escape the value
* @return string
*/
protected function evalTextTypeValue($record, $column, $value)
{
@ -1188,6 +1189,7 @@ class Lists extends WidgetBase
/**
* Process as number, proxy to text
* @return string
*/
protected function evalNumberTypeValue($record, $column, $value)
{

View File

@ -6,14 +6,12 @@ use App;
use View;
use Lang;
use Flash;
use Crypt;
use Config;
use Session;
use Request;
use Response;
use Exception;
use BackendAuth;
use Carbon\Carbon;
use Twig\Environment as TwigEnvironment;
use Twig\Cache\FilesystemCache as TwigCacheFilesystem;
use Cms\Twig\Loader as TwigLoader;
@ -27,7 +25,6 @@ use System\Twig\Extension as SystemTwigExtension;
use October\Rain\Exception\AjaxException;
use October\Rain\Exception\ValidationException;
use October\Rain\Parse\Bracket as TextParser;
use Symfony\Component\HttpFoundation\Cookie;
use Illuminate\Http\RedirectResponse;
use Symfony\Component\HttpFoundation\Response as BaseResponse;
@ -42,6 +39,7 @@ class Controller
{
use \System\Traits\AssetMaker;
use \System\Traits\EventEmitter;
use \System\Traits\SecurityController;
/**
* @var \Cms\Classes\Theme A reference to the CMS theme processed by the controller.
@ -1605,68 +1603,4 @@ class Controller
}
}
}
//
// Security
//
/**
* Adds anti-CSRF cookie.
* Adds a cookie with a token for CSRF checks to the response.
*
* @param BaseResponse $response The response object to add the cookie to
* @return BaseResponse
*/
protected function addXsrfCookie(BaseResponse $response)
{
$config = Config::get('session');
$response->headers->setCookie(
new Cookie(
'XSRF-TOKEN',
Session::token(),
Carbon::now()->addMinutes((int) $config['lifetime'])->getTimestamp(),
$config['path'],
$config['domain'],
$config['secure'],
false,
false,
$config['same_site'] ?? null
)
);
return $response;
}
/**
* 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', true)) {
return true;
}
if (in_array(Request::method(), ['HEAD', 'GET', 'OPTIONS'])) {
return true;
}
$token = Request::input('_token') ?: Request::header('X-CSRF-TOKEN');
if (!$token && $header = Request::header('X-XSRF-TOKEN')) {
$token = Crypt::decrypt($header);
}
if (!strlen($token) || !strlen(Session::token())) {
return false;
}
return hash_equals(
Session::token(),
$token
);
}
}

View File

@ -0,0 +1,98 @@
<?php namespace System\Traits;
use Crypt;
use Config;
use Request;
use Session;
use Carbon\Carbon;
use Symfony\Component\HttpFoundation\Response as BaseResponse;
use Symfony\Component\HttpFoundation\Cookie;
/**
* Security Controller Trait
* Adds cross-site scripting protection methods to a controller based class
*
* @package october\system
* @author Alexey Bobkov, Samuel Georges
*/
trait SecurityController
{
/**
* Adds anti-CSRF cookie.
* Adds a cookie with a token for CSRF checks to the response.
*
* @param BaseResponse $response The response object to add the cookie to
* @return BaseResponse
*/
protected function addXsrfCookie(BaseResponse $response)
{
$config = Config::get('session');
$response->headers->setCookie(
new Cookie(
'XSRF-TOKEN',
Session::token(),
Carbon::now()->addMinutes((int) $config['lifetime'])->getTimestamp(),
$config['path'],
$config['domain'],
$config['secure'],
false,
false,
$config['same_site'] ?? null
)
);
return $response;
}
/**
* 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', true)) {
return true;
}
if (in_array(Request::method(), ['HEAD', 'GET', 'OPTIONS'])) {
return true;
}
$token = Request::input('_token') ?: Request::header('X-CSRF-TOKEN');
if (!$token && $header = Request::header('X-XSRF-TOKEN')) {
$token = Crypt::decrypt($header, false);
}
if (!strlen($token) || !strlen(Session::token())) {
return false;
}
return hash_equals(
Session::token(),
$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;
}
}