Finished cleanup of account edit page

added csrf protection to account edit page under sitewide config
escaped all instances of CTOKEN for csrf in smarty templates
This commit is contained in:
xisi 2014-01-17 03:11:14 -05:00
parent 9ccb5e15bc
commit e5c9720174
7 changed files with 104 additions and 48 deletions

View File

@ -6,14 +6,19 @@ if (!defined('SECURITY'))
// twofactor stuff
$cp_editable = $wf_editable = $ea_editable = $wf_sent = $ea_sent = $cp_sent = 0;
$ea_token = (!isset($_POST['ea_token'])) ? '' : $_POST['ea_token'];
$cp_token = (!isset($_POST['cp_token'])) ? '' : $_POST['cp_token'];
$wf_token = (!isset($_POST['wf_token'])) ? '' : $_POST['wf_token'];
// set old token so we can use it if an error happens
$oldtoken_ea = ($ea_token !== '') ? $ea_token : '';
$oldtoken_wf = ($wf_token !== '') ? $wf_token : '';
$oldtoken_cp = ($cp_token !== '') ? $cp_token : '';
// 2fa - set old token so we can use it if an error happens or we need to use post
$oldtoken_ea = (isset($_POST['ea_token']) && $_POST['ea_token'] !== '') ? $_POST['ea_token'] : '';
$oldtoken_cp = (isset($_POST['cp_token']) && $_POST['cp_token'] !== '') ? $_POST['cp_token'] : '';
$oldtoken_wf = (isset($_POST['wf_token']) && $_POST['wf_token'] !== '') ? $_POST['wf_token'] : '';
$updating = (@$_POST['do']) ? 1 : 0;
// csrf stuff
$csrfenabled = ($config['csrf']['enabled'] && $config['csrf']['options']['sitewide']) ? 1 : 0;
if ($csrfenabled) {
$nocsrf = ($csrftoken->getBasic($user->getCurrentIP(), 'editaccount', 'mdyH') == @$_POST['ctoken']) ? 1 : 0;
$csrfvalid = 0;
}
if ($user->isAuthenticated()) {
if ($config['twofactor']['enabled']) {
@ -21,17 +26,17 @@ if ($user->isAuthenticated()) {
$popuptypes = array();
if ($config['twofactor']['options']['details']) {
$popuptypes[] = 'editing your details';
$ea_editable = $user->token->isTokenValid($_SESSION['USERDATA']['id'], $ea_token, 5);
$ea_editable = $user->token->isTokenValid($_SESSION['USERDATA']['id'], $oldtoken_ea, 5);
$ea_sent = $user->token->doesTokenExist('account_edit', $_SESSION['USERDATA']['id']);
}
if ($config['twofactor']['options']['changepw']) {
$popuptypes[] = 'changing your password';
$cp_editable = $user->token->isTokenValid($_SESSION['USERDATA']['id'], $cp_token, 6);
$cp_editable = $user->token->isTokenValid($_SESSION['USERDATA']['id'], $oldtoken_cp, 6);
$cp_sent = $user->token->doesTokenExist('change_pw', $_SESSION['USERDATA']['id']);
}
if ($config['twofactor']['options']['withdraw']) {
$popuptypes[] = 'withdrawals';
$wf_editable = $user->token->isTokenValid($_SESSION['USERDATA']['id'], $wf_token, 7);
$wf_editable = $user->token->isTokenValid($_SESSION['USERDATA']['id'], $oldtoken_wf, 7);
$wf_sent = $user->token->doesTokenExist('withdraw_funds', $_SESSION['USERDATA']['id']);
}
$ptc = 0;
@ -47,11 +52,22 @@ if ($user->isAuthenticated()) {
}
$_SESSION['POPUP'][] = array('CONTENT' => $popupmsg, 'TYPE' => 'info');
}
// if csrf is enabled sitewide check this token
if ($csrfenabled) {
$csrfvalid = ($nocsrf && $csrfenabled) ? 1 : 0;
}
if (isset($_POST['do']) && $_POST['do'] == 'genPin') {
if ($user->generatePin($_SESSION['USERDATA']['id'], $_POST['currentPassword'])) {
$_SESSION['POPUP'][] = array('CONTENT' => 'Your PIN # has been sent to your email.', 'TYPE' => 'success');
if (!$csrfenabled || $csrfenabled && $csrfvalid) {
if ($user->generatePin($_SESSION['USERDATA']['id'], $_POST['currentPassword'])) {
$_SESSION['POPUP'][] = array('CONTENT' => 'Your PIN # has been sent to your email.', 'TYPE' => 'success');
} else {
$_SESSION['POPUP'][] = array('CONTENT' => $user->getError(), 'TYPE' => 'errormsg');
}
} else {
$_SESSION['POPUP'][] = array('CONTENT' => $user->getError(), 'TYPE' => 'errormsg');
$img = $csrftoken->getDescriptionImageHTML();
$_SESSION['POPUP'][] = array('CONTENT' => "Edit account token expired, please try again $img", 'TYPE' => 'info');
}
}
else {
@ -63,25 +79,23 @@ if ($user->isAuthenticated()) {
$isvalid = in_array($_POST['utype'],$validtypes);
if ($isvalid) {
$ctype = strip_tags($_POST['utype']);
$send = $user->sendChangeConfigEmail($ctype, $_SESSION['USERDATA']['id']);
if ($send) {
$_SESSION['POPUP'][] = array('CONTENT' => 'A confirmation was sent to your e-mail, follow that link to continue', 'TYPE' => 'success');
if (!$csrfenabled || $csrfenabled && $csrfvalid) {
$send = $user->sendChangeConfigEmail($ctype, $_SESSION['USERDATA']['id']);
if ($send) {
$_SESSION['POPUP'][] = array('CONTENT' => 'A confirmation was sent to your e-mail, follow that link to continue', 'TYPE' => 'success');
} else {
$_SESSION['POPUP'][] = array('CONTENT' => $user->getError(), 'TYPE' => 'errormsg');
}
} else {
$_SESSION['POPUP'][] = array('CONTENT' => $user->getError(), 'TYPE' => 'errormsg');
$img = $csrftoken->getDescriptionImageHTML();
$_SESSION['POPUP'][] = array('CONTENT' => "Edit account token expired, please try again $img", 'TYPE' => 'info');
}
}
} else {
// back to get, was only post to fix for old token
$ea_token = (!isset($_GET['ea_token'])) ? '' : $_GET['ea_token'];
$cp_token = (!isset($_GET['cp_token'])) ? '' : $_GET['cp_token'];
$wf_token = (!isset($_GET['wf_token'])) ? '' : $_GET['wf_token'];
if ($ea_token == '' && isset($_POST['ea_token']) && strlen($_POST['ea_token']) > 1) {
$ea_token = $_POST['ea_token'];
} else if ($ea_token == '' && isset($_POST['cp_token']) && strlen($_POST['cp_token']) > 1) {
$cp_token = $_POST['cp_token'];
} else if ($wf_token == '' && isset($_POST['wf_token']) && strlen($_POST['wf_token']) > 1) {
$wf_token = $_POST['wf_token'];
}
// 2fa - when submitting we want the old token, otherwise we'll take what we can $_GET ... B^)
$ea_token = $updating ? $oldtoken_ea : @$_GET['ea_token'];
$wf_token = $updating ? $oldtoken_wf : @$_GET['wf_token'];
$cp_token = $updating ? $oldtoken_cp : @$_GET['cp_token'];
switch (@$_POST['do']) {
case 'cashOut':
@ -92,10 +106,15 @@ if ($user->isAuthenticated()) {
$dBalance = $aBalance['confirmed'];
if ($dBalance > $config['txfee']) {
if (!$oPayout->isPayoutActive($_SESSION['USERDATA']['id'])) {
if ($iPayoutId = $oPayout->createPayout($_SESSION['USERDATA']['id'], $wf_token)) {
$_SESSION['POPUP'][] = array('CONTENT' => 'Created new manual payout request with ID #' . $iPayoutId);
if (!$csrfenabled || $csrfenabled && $csrfvalid) {
if ($iPayoutId = $oPayout->createPayout($_SESSION['USERDATA']['id'], $wf_token)) {
$_SESSION['POPUP'][] = array('CONTENT' => 'Created new manual payout request with ID #' . $iPayoutId);
} else {
$_SESSION['POPUP'][] = array('CONTENT' => $iPayoutId->getError(), 'TYPE' => 'errormsg');
}
} else {
$_SESSION['POPUP'][] = array('CONTENT' => $iPayoutId->getError(), 'TYPE' => 'errormsg');
$img = $csrftoken->getDescriptionImageHTML();
$_SESSION['POPUP'][] = array('CONTENT' => "Edit account token expired, please try again $img", 'TYPE' => 'info');
}
} else {
$_SESSION['POPUP'][] = array('CONTENT' => 'You already have one active manual payout request.', 'TYPE' => 'errormsg');
@ -107,19 +126,29 @@ if ($user->isAuthenticated()) {
break;
case 'updateAccount':
if ($user->updateAccount($_SESSION['USERDATA']['id'], $_POST['paymentAddress'], $_POST['payoutThreshold'], $_POST['donatePercent'], $_POST['email'], $_POST['is_anonymous'], $ea_token)) {
$_SESSION['POPUP'][] = array('CONTENT' => 'Account details updated', 'TYPE' => 'success');
} else {
$_SESSION['POPUP'][] = array('CONTENT' => 'Failed to update your account: ' . $user->getError(), 'TYPE' => 'errormsg');
}
if (!$csrfenabled || $csrfenabled && $csrfvalid) {
if ($user->updateAccount($_SESSION['USERDATA']['id'], $_POST['paymentAddress'], $_POST['payoutThreshold'], $_POST['donatePercent'], $_POST['email'], $_POST['is_anonymous'], $ea_token)) {
$_SESSION['POPUP'][] = array('CONTENT' => 'Account details updated', 'TYPE' => 'success');
} else {
$_SESSION['POPUP'][] = array('CONTENT' => 'Failed to update your account: ' . $user->getError(), 'TYPE' => 'errormsg');
}
} else {
$img = $csrftoken->getDescriptionImageHTML();
$_SESSION['POPUP'][] = array('CONTENT' => "Edit account token expired, please try again $img", 'TYPE' => 'info');
}
break;
case 'updatePassword':
if ($user->updatePassword($_SESSION['USERDATA']['id'], $_POST['currentPassword'], $_POST['newPassword'], $_POST['newPassword2'], $cp_token)) {
$_SESSION['POPUP'][] = array('CONTENT' => 'Password updated', 'TYPE' => 'success');
} else {
$_SESSION['POPUP'][] = array('CONTENT' => $user->getError(), 'TYPE' => 'errormsg');
}
if (!$csrfenabled || $csrfenabled && $csrfvalid) {
if ($user->updatePassword($_SESSION['USERDATA']['id'], $_POST['currentPassword'], $_POST['newPassword'], $_POST['newPassword2'], $cp_token)) {
$_SESSION['POPUP'][] = array('CONTENT' => 'Password updated', 'TYPE' => 'success');
} else {
$_SESSION['POPUP'][] = array('CONTENT' => $user->getError(), 'TYPE' => 'errormsg');
}
} else {
$img = $csrftoken->getDescriptionImageHTML();
$_SESSION['POPUP'][] = array('CONTENT' => "Edit account token expired, please try again $img", 'TYPE' => 'info');
}
break;
}
}
@ -129,9 +158,9 @@ if ($user->isAuthenticated()) {
// 2fa - one last time so we can sync with changes we made during this page
if ($user->isAuthenticated() && $config['twofactor']['enabled']) {
// set the token to be the old token, just in case an error occured
$ea_token = ($oldtoken_ea !== '') ? $oldtoken_ea : $ea_token;
$wf_token = ($oldtoken_wf !== '') ? $oldtoken_wf : $wf_token;
$cp_token = ($oldtoken_cp !== '') ? $oldtoken_cp : $cp_token;
$ea_token = ($oldtoken_ea !== '') ? $oldtoken_ea : @$ea_token;
$wf_token = ($oldtoken_wf !== '') ? $oldtoken_wf : @$wf_token;
$cp_token = ($oldtoken_cp !== '') ? $oldtoken_cp : @$cp_token;
if ($config['twofactor']['options']['details']) {
$ea_editable = $user->token->isTokenValid($_SESSION['USERDATA']['id'], $ea_token, 5);
$ea_sent = $user->token->doesTokenExist('account_edit', $_SESSION['USERDATA']['id']);
@ -153,4 +182,9 @@ $smarty->assign("DETAILSUNLOCKED", $ea_editable);
$smarty->assign("CHANGEPASSSENT", $cp_sent);
$smarty->assign("WITHDRAWSENT", $wf_sent);
$smarty->assign("DETAILSSENT", $ea_sent);
// csrf token
if ($config['csrf']['enabled'] && $config['csrf']['options']['sitewide']) {
$token = $csrftoken->getBasic($user->getCurrentIP(), 'editaccount', 'mdyH');
$smarty->assign('CTOKEN', $token);
}
?>

View File

@ -56,6 +56,7 @@
<footer>
<div class="submit_link">
{nocache}
{if $GLOBAL.csrf.enabled && $GLOBAL.csrf.options.sitewide}<input type="hidden" name="ctoken" value="{$CTOKEN|escape}" />{/if}
<input type="hidden" name="ea_token" value="{$smarty.request.ea_token|escape}">
<input type="hidden" name="utype" value="account_edit">
{if $GLOBAL.twofactor.enabled && $GLOBAL.twofactor.options.details}
@ -105,6 +106,7 @@
<div class="submit_link">
{nocache}
<input type="hidden" name="wf_token" value="{$smarty.request.wf_token|escape}">
{if $GLOBAL.csrf.enabled && $GLOBAL.csrf.options.sitewide}<input type="hidden" name="ctoken" value="{$CTOKEN|escape}" />{/if}
<input type="hidden" name="utype" value="withdraw_funds">
{if $GLOBAL.twofactor.enabled && $GLOBAL.twofactor.options.withdraw}
{if $WITHDRAWSENT == 1 && $WITHDRAWUNLOCKED == 1}
@ -157,6 +159,7 @@
<div class="submit_link">
{nocache}
<input type="hidden" name="cp_token" value="{$smarty.request.cp_token|escape}">
{if $GLOBAL.csrf.enabled && $GLOBAL.csrf.options.sitewide}<input type="hidden" name="ctoken" value="{$CTOKEN|escape}" />{/if}
<input type="hidden" name="utype" value="change_pw">
{if $GLOBAL.twofactor.enabled && $GLOBAL.twofactor.options.changepw}
{if $CHANGEPASSSENT == 1 && $CHANGEPASSUNLOCKED == 1}
@ -180,6 +183,7 @@
<input type="hidden" name="page" value="{$smarty.request.page|escape}">
<input type="hidden" name="action" value="{$smarty.request.action|escape}">
<input type="hidden" name="do" value="genPin">
{if $GLOBAL.csrf.enabled && $GLOBAL.csrf.options.sitewide}<input type="hidden" name="ctoken" value="{$CTOKEN|escape}" />{/if}
<article class="module width_half">
<header>
<h3>Reset PIN</h3>

View File

@ -1,7 +1,7 @@
<form action="{$smarty.server.SCRIPT_NAME}" method="post">
<input type="hidden" name="page" value="{$smarty.request.page|escape}">
<input type="hidden" name="action" value="contactform">
{if $GLOBAL.csrf.enabled && $GLOBAL.csrf.options.sitewide}<input type="hidden" name="ctoken" value="{$CTOKEN}" />{/if}
{if $GLOBAL.csrf.enabled && $GLOBAL.csrf.options.sitewide}<input type="hidden" name="ctoken" value="{$CTOKEN|escape}" />{/if}
<article class="module width_3_quarter">
<header><h3>Contact Us</h3></header>
<div class="module_content">

View File

@ -1,7 +1,7 @@
<form action="{$smarty.server.SCRIPT_NAME}" method="post">
<input type="hidden" name="page" value="{$smarty.request.page|escape}">
<input type="hidden" name="action" value="contactform">
{if $GLOBAL.csrf.enabled && $GLOBAL.csrf.options.sitewide}<input type="hidden" name="ctoken" value="{$CTOKEN}" />{/if}
{if $GLOBAL.csrf.enabled && $GLOBAL.csrf.options.sitewide}<input type="hidden" name="ctoken" value="{$CTOKEN|escape}" />{/if}
<article class="module width_3_quarter">
<header><h3>Contact Us</h3></header>
<div class="module_content">

View File

@ -1,7 +1,7 @@
<article class="module width_half">
<form action="{$smarty.server.SCRIPT_NAME}?page=login" method="post" id="loginForm">
<input type="hidden" name="to" value="{($smarty.request.to|default:"{$smarty.server.SCRIPT_NAME}?page=dashboard")|escape}" />
{if $GLOBAL.csrf.enabled && $GLOBAL.csrf.forms.login}<input type="hidden" name="ctoken" value="{$CTOKEN}" />{/if}
{if $GLOBAL.csrf.enabled && $GLOBAL.csrf.forms.login}<input type="hidden" name="ctoken" value="{$CTOKEN|escape}" />{/if}
<header><h3>Login with existing account</h3></header>
<div class="module_content">
<fieldset>

View File

@ -0,0 +1,18 @@
{if $smarty.session.AUTHENTICATED|default:"0" == 0}
<div class="login_small">
<form action="{$smarty.server.SCRIPT_NAME}" method="post" id="loginForm">
<input type="hidden" name="page" value="login" />
{if $GLOBAL.csrf.enabled && $GLOBAL.csrf.forms.login}<input type="hidden" name="ctoken" value="{$CTOKEN|escape}" />{/if}
<input type="hidden" name="to" value="{$smarty.server.SCRIPT_NAME}?page=dashboard" />
<fieldset2 class="small">
<label>Username</label>
<input type="text" name="username" size="22" maxlength="100" required />
<fieldset2 class="small">
<label>Password</label>
<input type="password" name="password" size="22" maxlength="100" required />
</fieldset2>
</fieldset2>
<input type="submit" value="Login" class="alt_btn" />
</form>
</div>
{/if}

View File

@ -7,7 +7,7 @@
{if $smarty.request.token|default:""}
<input type="hidden" name="token" value="{$smarty.request.token|escape}" />
{/if}
{if $GLOBAL.csrf.enabled && $GLOBAL.csrf.forms.register}<input type="hidden" name="ctoken" value="{$CTOKEN}" />{/if}
{if $GLOBAL.csrf.enabled && $GLOBAL.csrf.forms.register}<input type="hidden" name="ctoken" value="{$CTOKEN|escape}" />{/if}
<input type="hidden" name="action" value="register">
<fieldset>
<label>Username</label>