parent
df65861aff
commit
f542ca8e90
|
|
@ -6,12 +6,14 @@ 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;
|
||||
|
|
@ -25,6 +27,7 @@ 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;
|
||||
|
||||
/**
|
||||
|
|
@ -147,6 +150,13 @@ class Controller
|
|||
$url = '/';
|
||||
}
|
||||
|
||||
/*
|
||||
* Check security token.
|
||||
*/
|
||||
if (!$this->verifyCsrfToken()) {
|
||||
return Response::make(Lang::get('system::lang.page.invalid_token.label'), 403);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hidden page
|
||||
*/
|
||||
|
|
@ -256,7 +266,13 @@ class Controller
|
|||
return $result;
|
||||
}
|
||||
|
||||
return Response::make($result, $this->statusCode);
|
||||
$response = Response::make($result, $this->statusCode);
|
||||
|
||||
if (Config::get('cms.enableCsrfProtection')) {
|
||||
$this->addCsrfCookie($response);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -802,13 +818,6 @@ class Controller
|
|||
*/
|
||||
protected function runAjaxHandler($handler)
|
||||
{
|
||||
/*
|
||||
* Check security token.
|
||||
*/
|
||||
if (!$this->verifyCsrfToken()) {
|
||||
return Response::make(Lang::get('system::lang.page.invalid_token.label'), 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* @event cms.ajax.beforeRunHandler
|
||||
* Provides an opportunity to modify an AJAX request
|
||||
|
|
@ -1583,6 +1592,32 @@ class Controller
|
|||
// Security
|
||||
//
|
||||
|
||||
/**
|
||||
* Adds anti-CSRF cookie.
|
||||
* Adds a cookie with a token for CSRF checks to the response.
|
||||
* @return void
|
||||
*/
|
||||
protected function addCsrfCookie(\Illuminate\Http\Response $response)
|
||||
{
|
||||
$config = Config::get('session');
|
||||
|
||||
$response->headers->setCookie(
|
||||
new Cookie(
|
||||
'XSRF-TOKEN',
|
||||
Session::token(),
|
||||
Carbon::now()->addSeconds(60 * $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
|
||||
|
|
@ -1601,6 +1636,10 @@ class Controller
|
|||
|
||||
$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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ useFiles=false}
|
|||
if($.type(loading)=='string'){loading=$(loading)}
|
||||
var requestHeaders={'X-OCTOBER-REQUEST-HANDLER':handler,'X-OCTOBER-REQUEST-PARTIALS':this.extractPartials(options.update)}
|
||||
if(useFlash){requestHeaders['X-OCTOBER-REQUEST-FLASH']=1}
|
||||
var csrfToken=getCSRFToken()
|
||||
if(csrfToken){requestHeaders['X-XSRF-TOKEN']=csrfToken}
|
||||
var requestData,inputName,data={}
|
||||
$.each($el.parents('[data-request-data]').toArray().reverse(),function extendRequest(){$.extend(data,paramToObj('data-request-data',$(this).data('request-data')))})
|
||||
if($el.is(':input')&&!$form.length){inputName=$el.attr('name')
|
||||
|
|
@ -112,6 +114,12 @@ function paramToObj(name,value){if(value===undefined)value=''
|
|||
if(typeof value=='object')return value
|
||||
try{return ocJSON("{"+value+"}")}
|
||||
catch(e){throw new Error('Error parsing the '+name+' attribute value. '+e)}}
|
||||
function getCSRFToken(){var cookieValue=null
|
||||
if(document.cookie&&document.cookie!=''){var cookies=document.cookie.split(';')
|
||||
for(var i=0;i<cookies.length;i++){var cookie=jQuery.trim(cookies[i])
|
||||
if(cookie.substring(0,11)==('XSRF-TOKEN'+'=')){cookieValue=decodeURIComponent(cookie.substring(11))
|
||||
break}}}
|
||||
return cookieValue}
|
||||
$(document).on('change','select[data-request], input[type=radio][data-request], input[type=checkbox][data-request], input[type=file][data-request]',function documentOnChange(){$(this).request()})
|
||||
$(document).on('click','a[data-request], button[data-request], input[type=button][data-request], input[type=submit][data-request]',function documentOnClick(e){e.preventDefault()
|
||||
$(this).request()
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ useFiles=false}
|
|||
if($.type(loading)=='string'){loading=$(loading)}
|
||||
var requestHeaders={'X-OCTOBER-REQUEST-HANDLER':handler,'X-OCTOBER-REQUEST-PARTIALS':this.extractPartials(options.update)}
|
||||
if(useFlash){requestHeaders['X-OCTOBER-REQUEST-FLASH']=1}
|
||||
var csrfToken=getCSRFToken()
|
||||
if(csrfToken){requestHeaders['X-XSRF-TOKEN']=csrfToken}
|
||||
var requestData,inputName,data={}
|
||||
$.each($el.parents('[data-request-data]').toArray().reverse(),function extendRequest(){$.extend(data,paramToObj('data-request-data',$(this).data('request-data')))})
|
||||
if($el.is(':input')&&!$form.length){inputName=$el.attr('name')
|
||||
|
|
@ -112,6 +114,12 @@ function paramToObj(name,value){if(value===undefined)value=''
|
|||
if(typeof value=='object')return value
|
||||
try{return ocJSON("{"+value+"}")}
|
||||
catch(e){throw new Error('Error parsing the '+name+' attribute value. '+e)}}
|
||||
function getCSRFToken(){var cookieValue=null
|
||||
if(document.cookie&&document.cookie!=''){var cookies=document.cookie.split(';')
|
||||
for(var i=0;i<cookies.length;i++){var cookie=jQuery.trim(cookies[i])
|
||||
if(cookie.substring(0,11)==('XSRF-TOKEN'+'=')){cookieValue=decodeURIComponent(cookie.substring(11))
|
||||
break}}}
|
||||
return cookieValue}
|
||||
$(document).on('change','select[data-request], input[type=radio][data-request], input[type=checkbox][data-request], input[type=file][data-request]',function documentOnChange(){$(this).request()})
|
||||
$(document).on('click','a[data-request], button[data-request], input[type=button][data-request], input[type=submit][data-request]',function documentOnClick(e){e.preventDefault()
|
||||
$(this).request()
|
||||
|
|
|
|||
|
|
@ -68,6 +68,11 @@ if (window.jQuery.request !== undefined) {
|
|||
requestHeaders['X-OCTOBER-REQUEST-FLASH'] = 1
|
||||
}
|
||||
|
||||
var csrfToken = getCSRFToken()
|
||||
if (csrfToken) {
|
||||
requestHeaders['X-XSRF-TOKEN'] = csrfToken
|
||||
}
|
||||
|
||||
/*
|
||||
* Request data
|
||||
*/
|
||||
|
|
@ -465,6 +470,21 @@ if (window.jQuery.request !== undefined) {
|
|||
}
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
var cookieValue = null
|
||||
if (document.cookie && document.cookie != '') {
|
||||
var cookies = document.cookie.split(';')
|
||||
for (var i = 0; i < cookies.length; i++) {
|
||||
var cookie = jQuery.trim(cookies[i])
|
||||
if (cookie.substring(0, 11) == ('XSRF-TOKEN' + '=')) {
|
||||
cookieValue = decodeURIComponent(cookie.substring(11))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return cookieValue
|
||||
}
|
||||
|
||||
$(document).on('change', 'select[data-request], input[type=radio][data-request], input[type=checkbox][data-request], input[type=file][data-request]', function documentOnChange() {
|
||||
$(this).request()
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue