Merge pull request #2227 from MPOS/admin-csrf-protection

[FIX] CSRF protection for admin settings/user/news
This commit is contained in:
Sebastian Grewe 2014-06-10 15:08:34 +02:00
commit 1d5e69d219
7 changed files with 67 additions and 52 deletions

View File

@ -18,11 +18,11 @@ class Tools extends Base {
curl_setopt($curl, CURLOPT_HEADER, false); curl_setopt($curl, CURLOPT_HEADER, false);
$data = curl_exec($curl); $data = curl_exec($curl);
preg_match('/define\(\'MPOS_VERSION\', \'(.*)\'\);/', $data, $match); preg_match('/define\(\'MPOS_VERSION\', \'(.*)\'\);/', $data, $match);
$mpos_versions['MPOS_VERSION'] = $match[1]; $mpos_versions['MPOS_VERSION'] = @$match[1];
preg_match('/define\(\'DB_VERSION\', \'(.*)\'\);/', $data, $match); preg_match('/define\(\'DB_VERSION\', \'(.*)\'\);/', $data, $match);
$mpos_versions['DB_VERSION'] = $match[1]; $mpos_versions['DB_VERSION'] = @$match[1];
preg_match('/define\(\'CONFIG_VERSION\', \'(.*)\'\);/', $data, $match); preg_match('/define\(\'CONFIG_VERSION\', \'(.*)\'\);/', $data, $match);
$mpos_versions['CONFIG_VERSION'] = $match[1]; $mpos_versions['CONFIG_VERSION'] = @$match[1];
curl_close($curl); curl_close($curl);
return $this->memcache->setCache($key, $mpos_versions, 30); return $this->memcache->setCache($key, $mpos_versions, 30);
} else { } else {

View File

@ -10,24 +10,32 @@ if (!$user->isAuthenticated() || !$user->isAdmin($_SESSION['USERDATA']['id'])) {
// Include markdown library // Include markdown library
use \Michelf\Markdown; use \Michelf\Markdown;
if (@$_REQUEST['do'] == 'toggle_active') if (@$_REQUEST['do'] == 'toggle_active') {
if ($news->toggleActive($_REQUEST['id'])) if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) {
if ($news->toggleActive($_REQUEST['id'])) {
$_SESSION['POPUP'][] = array('CONTENT' => 'News entry changed', 'TYPE' => 'alert alert-success'); $_SESSION['POPUP'][] = array('CONTENT' => 'News entry changed', 'TYPE' => 'alert alert-success');
}
}
}
if (@$_REQUEST['do'] == 'add') { if (@$_REQUEST['do'] == 'add') {
if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) {
if ($news->addNews($_SESSION['USERDATA']['id'], $_POST['data'])) { if ($news->addNews($_SESSION['USERDATA']['id'], $_POST['data'])) {
$_SESSION['POPUP'][] = array('CONTENT' => 'News entry added', 'TYPE' => 'alert alert-success'); $_SESSION['POPUP'][] = array('CONTENT' => 'News entry added', 'TYPE' => 'alert alert-success');
} else { } else {
$_SESSION['POPUP'][] = array('CONTENT' => 'Failed to add new entry: ' . $news->getError(), 'TYPE' => 'alert alert-danger'); $_SESSION['POPUP'][] = array('CONTENT' => 'Failed to add new entry: ' . $news->getError(), 'TYPE' => 'alert alert-danger');
} }
}
} }
if (@$_REQUEST['do'] == 'delete') { if (@$_REQUEST['do'] == 'delete') {
if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) {
if ($news->deleteNews((int)$_REQUEST['id'])) { if ($news->deleteNews((int)$_REQUEST['id'])) {
$_SESSION['POPUP'][] = array('CONTENT' => 'Succesfully removed news entry', 'TYPE' => 'alert alert-success'); $_SESSION['POPUP'][] = array('CONTENT' => 'Succesfully removed news entry', 'TYPE' => 'alert alert-success');
} else { } else {
$_SESSION['POPUP'][] = array('CONTENT' => 'Failed to delete entry: ' . $news->getError(), 'TYPE' => 'alert alert-danger'); $_SESSION['POPUP'][] = array('CONTENT' => 'Failed to delete entry: ' . $news->getError(), 'TYPE' => 'alert alert-danger');
} }
}
} }
// Fetch all news // Fetch all news

View File

@ -10,12 +10,14 @@ if (!$user->isAuthenticated() || !$user->isAdmin($_SESSION['USERDATA']['id'])) {
// Include markdown library // Include markdown library
use \Michelf\Markdown; use \Michelf\Markdown;
if (@$_REQUEST['do'] == 'save') { if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) {
if (@$_REQUEST['do'] == 'save') {
if ($news->updateNews($_REQUEST['id'], $_REQUEST['header'], $_REQUEST['content'], $_REQUEST['active'])) { if ($news->updateNews($_REQUEST['id'], $_REQUEST['header'], $_REQUEST['content'], $_REQUEST['active'])) {
$_SESSION['POPUP'][] = array('CONTENT' => 'News updated', 'TYPE' => 'alert alert-success'); $_SESSION['POPUP'][] = array('CONTENT' => 'News updated', 'TYPE' => 'alert alert-success');
} else { } else {
$_SESSION['POPUP'][] = array('CONTENT' => 'News update failed: ' . $news->getError(), 'TYPE' => 'alert alert-danger'); $_SESSION['POPUP'][] = array('CONTENT' => 'News update failed: ' . $news->getError(), 'TYPE' => 'alert alert-danger');
} }
}
} }
// Fetch news entry // Fetch news entry

View File

@ -8,11 +8,15 @@ if (!$user->isAuthenticated() || !$user->isAdmin($_SESSION['USERDATA']['id'])) {
} }
if (@$_REQUEST['do'] == 'save' && !empty($_REQUEST['data'])) { if (@$_REQUEST['do'] == 'save' && !empty($_REQUEST['data'])) {
if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) {
$user->log->log("warn", @$_SESSION['USERDATA']['username']." changed admin settings"); $user->log->log("warn", @$_SESSION['USERDATA']['username']." changed admin settings");
foreach($_REQUEST['data'] as $var => $value) { foreach($_REQUEST['data'] as $var => $value) {
$setting->setValue($var, $value); $setting->setValue($var, $value);
} }
$_SESSION['POPUP'][] = array('CONTENT' => 'Settings updated', 'TYPE' => 'alert alert-success'); $_SESSION['POPUP'][] = array('CONTENT' => 'Settings updated', 'TYPE' => 'alert alert-success');
} else {
$_SESSION['POPUP'][] = array('CONTENT' => $csrftoken->getErrorWithDescriptionHTML(), 'TYPE' => 'alert alert-warning');
}
} }
// Load our available settings from configuration // Load our available settings from configuration

View File

@ -16,8 +16,9 @@ $smarty->assign('LOCKED', array('' => '', '0' => 'No', '1' => 'Yes'));
$smarty->assign('NOFEE', array('' => '', '0' => 'No', '1' => 'Yes')); $smarty->assign('NOFEE', array('' => '', '0' => 'No', '1' => 'Yes'));
// Catch our JS queries to update some settings // Catch our JS queries to update some settings
switch (@$_REQUEST['do']) { if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) {
case 'lock': switch (@$_REQUEST['do']) {
case 'lock':
$supress_master = 1; $supress_master = 1;
// Reset user account // Reset user account
if ($user->isLocked($_POST['account_id']) == 0) { if ($user->isLocked($_POST['account_id']) == 0) {
@ -28,14 +29,15 @@ case 'lock':
$user->setUserPinFailed($_POST['account_id'], 0); $user->setUserPinFailed($_POST['account_id'], 0);
} }
break; break;
case 'fee': case 'fee':
$supress_master = 1; $supress_master = 1;
$user->changeNoFee($_POST['account_id']); $user->changeNoFee($_POST['account_id']);
break; break;
case 'admin': case 'admin':
$supress_master = 1; $supress_master = 1;
$user->changeAdmin($_POST['account_id']); $user->changeAdmin($_POST['account_id']);
break; break;
}
} }
// Gernerate the GET URL for filters // Gernerate the GET URL for filters

View File

@ -53,7 +53,7 @@
<div class="panel-footer"> <div class="panel-footer">
<div style="text-align:right"> <div style="text-align:right">
<a href='{$smarty.server.SCRIPT_NAME}?page={$smarty.request.page|escape}&action=news_edit&id={$NEWS[news].id}'><i class="fa fa-wrench fa-fw"></i></a>&nbsp; <a href='{$smarty.server.SCRIPT_NAME}?page={$smarty.request.page|escape}&action=news_edit&id={$NEWS[news].id}'><i class="fa fa-wrench fa-fw"></i></a>&nbsp;
<a href='{$smarty.server.SCRIPT_NAME}?page={$smarty.request.page|escape}&action={$smarty.request.action|escape}&do=delete&id={$NEWS[news].id}'><i class="fa fa-trash-o fa-fw"></i></a> <a href='{$smarty.server.SCRIPT_NAME}?page={$smarty.request.page|escape}&action={$smarty.request.action|escape}&do=delete&id={$NEWS[news].id}&ctoken={$CTOKEN|escape|default:""}'><i class="fa fa-trash-o fa-fw"></i></a>
</div> </div>
</div> </div>
</div> </div>
@ -61,4 +61,3 @@
{/section} {/section}
{/nocache} {/nocache}
</div> </div>

View File

@ -3,21 +3,21 @@
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: "{$smarty.server.SCRIPT_NAME}", url: "{$smarty.server.SCRIPT_NAME}",
data: "page={$smarty.request.page|escape}&action={$smarty.request.action|escape}&do=fee&account_id=" + id, data: "page={$smarty.request.page|escape}&action={$smarty.request.action|escape}&do=fee&account_id=" + id + "&ctoken={$smarty.request.ctoken|escape}",
}); });
} }
function storeLock(id) { function storeLock(id) {
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: "{$smarty.server.SCRIPT_NAME}", url: "{$smarty.server.SCRIPT_NAME}",
data: "page={$smarty.request.page|escape}&action={$smarty.request.action|escape}&do=lock&account_id=" + id, data: "page={$smarty.request.page|escape}&action={$smarty.request.action|escape}&do=lock&account_id=" + id + "&ctoken={$smarty.request.ctoken|escape}",
}); });
} }
function storeAdmin(id) { function storeAdmin(id) {
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: "{$smarty.server.SCRIPT_NAME}", url: "{$smarty.server.SCRIPT_NAME}",
data: "page={$smarty.request.page|escape}&action={$smarty.request.action|escape}&do=admin&account_id=" + id, data: "page={$smarty.request.page|escape}&action={$smarty.request.action|escape}&do=admin&account_id=" + id + "&ctoken={$smarty.request.ctoken|escape}",
}); });
} }
</script> </script>