Fix CSRF security issue.
This commit is contained in:
davidcallizaya
2017-10-13 07:57:22 -04:00
parent 592ab76c01
commit 086cc31982
12 changed files with 112 additions and 68 deletions

View File

@@ -323,8 +323,7 @@ class PmBootstrap extends Bootstrap
require_once 'classes/model/Users.php';
$oUser = new Users();
$aUser = $oUser->load($aSession['USR_UID']);
$_SESSION['USER_LOGGED'] = $aUser['USR_UID'];
$_SESSION['USR_USERNAME'] = $aUser['USR_USERNAME'];
initUserSession($aUser['USR_UID'], $aUser['USR_USERNAME']);
$bRedirect = false;
$RBAC->initRBAC();
$RBAC->loadUserRolePermission( $RBAC->sSystem, $_SESSION['USER_LOGGED'] );

View File

@@ -182,14 +182,12 @@ try {
$oPluginRegistry->executeTriggers ( PM_LOGIN , $loginInfo );
}
EnterpriseClass::enterpriseSystemUpdate($loginInfo);
$_SESSION['USER_LOGGED'] = $uid;
$_SESSION['USR_USERNAME'] = $usr;
initUserSession($uid, $usr);
} else {
setcookie("singleSignOn", '1', time() + (24 * 60 * 60), '/');
$uid = $RBAC->userObj->fields['USR_UID'];
$usr = $RBAC->userObj->fields['USR_USERNAME'];
$_SESSION['USER_LOGGED'] = $uid;
$_SESSION['USR_USERNAME'] = $usr;
initUserSession($uid, $usr);
}
//Set default Languaje

View File

@@ -129,9 +129,10 @@ try {
setcookie('singleSignOn', '1', time() + (24 * 60 * 60), '/');
$_SESSION['USER_LOGGED'] = $_SESSION['__USER_LOGGED_SSO__'];
$_SESSION['USR_USERNAME'] = $_SESSION['__USR_USERNAME_SSO__'];
initUserSession(
$_SESSION['__USER_LOGGED_SSO__'],
$_SESSION['__USR_USERNAME_SSO__']
);
unset($_SESSION['__USER_LOGGED_SSO__'], $_SESSION['__USR_USERNAME_SSO__']);
G::header('Location: ' . $location);

View File

@@ -4,7 +4,6 @@ ini_set("max_execution_time", 0);
$filter = new InputFilter();
$_FILES = $filter->xssFilterHard($_FILES);
$_SESSION['USER_LOGGED'] = $filter->xssFilterHard($_SESSION['USER_LOGGED']);
if (isset($_FILES["PROCESS_FILENAME"]) &&
pathinfo($_FILES["PROCESS_FILENAME"]["name"], PATHINFO_EXTENSION) == "bpmn"

View File

@@ -24,8 +24,7 @@ try {
throw new \Exception('WebEntry User not found');
}
$_SESSION['USER_LOGGED'] = $userUid;
$_SESSION['USR_USERNAME'] = $userInfo['username'];
initUserSession($userUid, $userInfo['username']);
$result = [
'user_logged' => $userUid,

View File

@@ -129,6 +129,7 @@ switch ($_POST['action']) {
case 'saveUser':
case 'savePersonalInfo':
try {
verifyCsrfToken($_POST);
$user = new \ProcessMaker\BusinessModel\User();
$form = $_POST;
$permissionsToSaveData = $user->getPermissionsForEdit();

View File

@@ -261,9 +261,11 @@ class SkinEngine
$template = new TemplatePower($templateFile);
$template->prepare();
$header = '<meta name="csrf-token" content="'. csrfToken().'" />' . "\n" . $header;
$template->assign('header', $header);
$template->assign('styles', $styles);
$template->assign('bodyTemplate', $body);
$template->assign('csrf_token', csrfToken());
$doctype = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
$meta = null;
@@ -569,6 +571,7 @@ class SkinEngine
$smarty->cache_dir = PATH_SMARTY_CACHE;
$smarty->config_dir = PATH_THIRDPARTY . 'smarty/configs';
$smarty->register_function('translate', 'translate');
$smarty->register_function('csrf_token', 'csrfToken');
$viewVars = $oHeadPublisher->getVars();

View File

@@ -1,4 +1,8 @@
<?php
use Illuminate\Session\TokenMismatchException;
use Illuminate\Support\Str;
/**
* We will send a case note in the actions by email
* @param object $httpData
@@ -361,3 +365,33 @@ function eprintln ($s = "", $c = null)
print "$s\n";
}
}
/**
* Initialize the user logged session
*/
function initUserSession($usrUid, $usrName)
{
$_SESSION['USER_LOGGED'] = $usrUid;
$_SESSION['USR_USERNAME'] = $usrName;
$_SESSION['USR_CSRF_TOKEN'] = Str::random(40);
}
function verifyCsrfToken($request)
{
$headers = getallheaders();
$token = isset($request['_token'])
? $request['_token']
: (isset($headers['X-CSRF-TOKEN'])
? $headers['X-CSRF-TOKEN']
: null);
$match = is_string($_SESSION['USR_CSRF_TOKEN'])
&& is_string($token)
&& hash_equals($_SESSION['USR_CSRF_TOKEN'], $token);
if (!$match) {
throw new TokenMismatchException();
}
}
function csrfToken()
{
return isset($_SESSION['USR_CSRF_TOKEN']) ? $_SESSION['USR_CSRF_TOKEN'] : '';
}

View File

@@ -809,6 +809,12 @@ Ext.onReady(function () {
comboDefaultCasesMenuOption
]
});
var csrfToken = {
xtype : 'hidden',
name : '_token',
value : document.querySelector('meta[name="csrf-token"]').content
};
frmDetails = new Ext.FormPanel({
id : 'frmDetails',
@@ -828,6 +834,7 @@ Ext.onReady(function () {
align : 'center'
},
items : [
csrfToken,
informationFields,
/*----------------------------------********---------------------------------*/
costByHour,

View File

@@ -644,8 +644,7 @@ use ProcessMaker\Plugins\PluginRegistry;
require_once 'classes/model/Users.php';
$oUser = new Users();
$aUser = $oUser->load($aSession['USR_UID']);
$_SESSION['USER_LOGGED'] = $aUser['USR_UID'];
$_SESSION['USR_USERNAME'] = $aUser['USR_USERNAME'];
initUserSession($aUser['USR_UID'], $aUser['USR_USERNAME']);
$bRedirect = false;
if (PHP_VERSION < 5.2) {
setcookie(session_name(), session_id(), time() + $timelife, '/', '; HttpOnly');

View File

@@ -15,7 +15,7 @@ $server = isset($_GET['server']) ? $_GET['server'] : '';
//We do need the server to continue.
if( !isset($_GET['server']) || $server == "" ){
throw new \Exception(Bootstrap::LoadTranslation( 'ID_GMAIL_NEED_SERVER' ));
throw new \Exception(Bootstrap::LoadTranslation( 'ID_GMAIL_NEED_SERVER' ));
}
//First check if the feature is enabled in the license.
@@ -53,75 +53,77 @@ curl_close($curl);
$decodedResp = G::json_decode($curl_response);
if(!is_object($decodedResp) || property_exists($decodedResp,'error')) {
die($decodedResp->error->message);
die($decodedResp->error->message);
}
//getting the enviroment
$enviroment = $decodedResp->enviroment;
if(count($decodedResp->user) > 1){
echo Bootstrap::LoadTranslation( 'ID_EMAIL_MORE_THAN_ONE_USER' );
die;
echo Bootstrap::LoadTranslation( 'ID_EMAIL_MORE_THAN_ONE_USER' );
die;
} else if(count($decodedResp->user) < 1){
echo Bootstrap::LoadTranslation( 'ID_USER_NOT_FOUND' );
die;
echo Bootstrap::LoadTranslation( 'ID_USER_NOT_FOUND' );
die;
}
//validationg if there is an actual PM session
if( !isset($_SESSION['USER_LOGGED']) || $_SESSION['USER_LOGGED'] != $decodedResp->user['0']->USR_UID){
$url = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='.$gmailToken;
$url = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='.$gmailToken;
// init curl object
$ch = curl_init();
// define options
$optArray = array(
// init curl object
$ch = curl_init();
// define options
$optArray = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false
);
// apply those options
curl_setopt_array($ch, $optArray);
// execute request and get response
$result = curl_exec($ch);
$response = (G::json_decode($result));
curl_close($ch);
);
// apply those options
curl_setopt_array($ch, $optArray);
// execute request and get response
$result = curl_exec($ch);
$response = (G::json_decode($result));
curl_close($ch);
//First validate if this user (mail) corresponds to a PM user
if(isset($response->email) && ($gmail == $response->email)){
//If the email corresponds I get the username and with the gmail user_id the session is created.
if($decodedResp->user['0']->USR_STATUS == "ACTIVE"){
//User Active! lets create the Session
@session_destroy();
session_start();
session_regenerate_id();
if (PHP_VERSION < 5.2) {
setcookie("workspaceSkin", $enviroment, time() + (24 * 60 * 60), "/sys" . $enviroment, "; HttpOnly");
} else {
setcookie("workspaceSkin", $enviroment, time() + (24 * 60 * 60), "/sys" . $enviroment, null, false, true);
}
//First validate if this user (mail) corresponds to a PM user
if(isset($response->email) && ($gmail == $response->email)){
//If the email corresponds I get the username and with the gmail user_id the session is created.
if($decodedResp->user['0']->USR_STATUS == "ACTIVE"){
//User Active! lets create the Session
@session_destroy();
session_start();
session_regenerate_id();
$_SESSION = array();
$_SESSION['__EE_INSTALLATION__'] = 2;
$_SESSION['__EE_SW_PMLICENSEMANAGER__'] = 1;
$_SESSION['phpLastFileFound'] = '';
$_SESSION['USERNAME_PREVIOUS1'] = $decodedResp->user['0']->USR_USERNAME;
$_SESSION['USERNAME_PREVIOUS2'] = $decodedResp->user['0']->USR_USERNAME;
$_SESSION['WORKSPACE'] = $pmws;
$_SESSION['USER_LOGGED'] = $decodedResp->user['0']->USR_UID;
$_SESSION['USR_USERNAME'] = $decodedResp->user['0']->USR_USERNAME;
$_SESSION['USR_FULLNAME'] = $decodedResp->user['0']->USR_FIRSTNAME. ' ' .$decodedResp->user['0']->USR_LASTNAME;
$_SESSION['__sw__'] = 1;
//session created
} else {
echo Bootstrap::LoadTranslation( 'ID_USER_NOT_ACTIVE' );
die;
}
} else {
echo Bootstrap::LoadTranslation( 'ID_USER_DOES_NOT_CORRESPOND' );
die;
}
if (PHP_VERSION < 5.2) {
setcookie("workspaceSkin", $enviroment, time() + (24 * 60 * 60), "/sys" . $enviroment, "; HttpOnly");
} else {
setcookie("workspaceSkin", $enviroment, time() + (24 * 60 * 60), "/sys" . $enviroment, null, false, true);
}
$_SESSION = array();
$_SESSION['__EE_INSTALLATION__'] = 2;
$_SESSION['__EE_SW_PMLICENSEMANAGER__'] = 1;
$_SESSION['phpLastFileFound'] = '';
$_SESSION['USERNAME_PREVIOUS1'] = $decodedResp->user['0']->USR_USERNAME;
$_SESSION['USERNAME_PREVIOUS2'] = $decodedResp->user['0']->USR_USERNAME;
$_SESSION['WORKSPACE'] = $pmws;
$_SESSION['USR_FULLNAME'] = $decodedResp->user['0']->USR_FIRSTNAME. ' ' .$decodedResp->user['0']->USR_LASTNAME;
$_SESSION['__sw__'] = 1;
initUserSession(
$decodedResp->user['0']->USR_UID,
$decodedResp->user['0']->USR_USERNAME
);
//session created
} else {
echo Bootstrap::LoadTranslation( 'ID_USER_NOT_ACTIVE' );
die;
}
} else {
echo Bootstrap::LoadTranslation( 'ID_USER_DOES_NOT_CORRESPOND' );
die;
}
}
$_SESSION['server'] = 'https://' . $server . '/sys'. $pmws .'/en/'.$enviroment.'/';

View File

@@ -979,8 +979,10 @@ if (! defined( 'EXECUTE_BY_CRON' )) {
require_once 'classes/model/Users.php';
$oUser = new Users();
$aUser = $oUser->load( $aSession['USR_UID'] );
$_SESSION['USER_LOGGED'] = $aUser['USR_UID'];
$_SESSION['USR_USERNAME'] = $aUser['USR_USERNAME'];
initUserSession(
$_SESSION['USER_LOGGED'],
$aUser['USR_USERNAME']
);
$bRedirect = false;
if ((preg_match("/msie/i", $_SERVER ['HTTP_USER_AGENT']) != 1 ||
$config['ie_cookie_lifetime'] == 1) &&