basic logging, adds logs folder to root dir

htaccess to block access to the logs
by default, only log warnings
simple config check to see if that folder is writable

warning if changeNoFee is used
warning if setLocked is used
warning if changeAdmin is used
warning if when logging in that IP is different than saved IP
info if a login fails with bad user or password
warning if a user is locked via failed logins
info if an update/etc fails with bad pin
warning if a user is locked via failed pins
info when a pin request is sent
warning when a pin request email doesn't send
warning when trying to request pin reset and incorrect password
info when a twofactor token sent
warning if twofactor email doesn't send
warning when a user tries to request multiple of the same type of token
info when a twofactor token is deleted
warning if a twofactor token fails to delete
warning when an invalid change password token is used
info on successful account update
warning when reset password is called and IP doesn't match saved IP, info otherwise
warning if isAuthenticated falls through and kills a session
This commit is contained in:
xisi 2014-01-31 13:11:38 -05:00
parent afdf3abb29
commit e7bace5550
13 changed files with 172 additions and 29 deletions

1
.gitignore vendored
View File

@ -11,6 +11,7 @@
# Logs # Logs
/cronjobs/logs/*.txt /cronjobs/logs/*.txt
/cronjobs/logs/*.txt.*.gz /cronjobs/logs/*.txt.*.gz
/logs/*
# Test configs # Test configs
public/include/config/global.inc.scrypt.php public/include/config/global.inc.scrypt.php

3
.htaccess Normal file
View File

@ -0,0 +1,3 @@
ErrorDocument 404 /public/index.php?page=error&action=404
RedirectMatch 404 /logs(/|$)
Options -Indexes

1
logs/README.md Normal file
View File

@ -0,0 +1 @@
hi

View File

@ -15,6 +15,12 @@ if (@$_SESSION['USERDATA']['is_admin'] && $user->isAdmin(@$_SESSION['USERDATA'][
} }
// setup checks // setup checks
// logging
if ($config['logging']['enabled']) {
if (!is_writable($config['logging']['path'])) {
$error[] = "Logging is enabled but we can't write in the logging path";
}
}
// check if memcache isn't available but enabled in config -> error // check if memcache isn't available but enabled in config -> error
if (!class_exists('Memcached') && $config['memcache']['enabled']) { if (!class_exists('Memcached') && $config['memcache']['enabled']) {
$error[] = "You have memcache enabled in your config and it's not available. Install the package on your system."; $error[] = "You have memcache enabled in your config and it's not available. Install the package on your system.";

View File

@ -12,6 +12,9 @@ if (empty($config['algorithm']) || $config['algorithm'] == 'scrypt') {
// Default classes // Default classes
require_once(CLASS_DIR . '/debug.class.php'); require_once(CLASS_DIR . '/debug.class.php');
require_once(INCLUDE_DIR . '/lib/KLogger.php'); require_once(INCLUDE_DIR . '/lib/KLogger.php');
if ($config['logging']['enabled']) {
$log = new KLogger($config['logging']['path']."/".$config['logging']['file'], $config['logging']['level']);
}
if ($config['mysql_filter']) { if ($config['mysql_filter']) {
require_once(CLASS_DIR . '/strict.class.php'); require_once(CLASS_DIR . '/strict.class.php');
} }

View File

@ -19,6 +19,9 @@ class Base {
public function setDebug($debug) { public function setDebug($debug) {
$this->debug = $debug; $this->debug = $debug;
} }
public function setLog($log) {
$this->log = $log;
}
public function setMysql($mysqli) { public function setMysql($mysqli) {
$this->mysqli = $mysqli; $this->mysqli = $mysqli;
} }

View File

@ -120,6 +120,9 @@ class Notification extends Mail {
$this->setErrorMessage($this->getErrorMsg('E0047', $failed)); $this->setErrorMessage($this->getErrorMsg('E0047', $failed));
return $this->sqlError(); return $this->sqlError();
} }
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogInfo("User $account_id updated notification settings from [".$_SERVER['REMOTE_ADDR']."]");
}
return true; return true;
} }
@ -154,6 +157,7 @@ class Notification extends Mail {
$notification = new Notification(); $notification = new Notification();
$notification->setDebug($debug); $notification->setDebug($debug);
$notification->setLog($log);
$notification->setMysql($mysqli); $notification->setMysql($mysqli);
$notification->setSmarty($smarty); $notification->setSmarty($smarty);
$notification->setConfig($config); $notification->setConfig($config);

View File

@ -41,8 +41,20 @@ class Payout Extends Base {
if ($this->config['twofactor']['enabled'] && $this->config['twofactor']['options']['withdraw']) { if ($this->config['twofactor']['enabled'] && $this->config['twofactor']['options']['withdraw']) {
$tValid = $this->token->isTokenValid($account_id, $strToken, 7); $tValid = $this->token->isTokenValid($account_id, $strToken, 7);
if ($tValid) { if ($tValid) {
$this->token->deleteToken($strToken); $delete = $this->token->deleteToken($strToken);
if ($delete) {
return true;
} else {
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogInfo("User $account_id requested manual payout but the token deletion failed from [".$_SERVER['REMOTE_ADDR']."]");
}
$this->setErrorMessage('Unable to delete token');
return false;
}
} else { } else {
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogInfo("User $account_id requested manual payout using an invalid token from [".$_SERVER['REMOTE_ADDR']."]");
}
$this->setErrorMessage('Invalid token'); $this->setErrorMessage('Invalid token');
return false; return false;
} }
@ -67,6 +79,7 @@ class Payout Extends Base {
$oPayout = new Payout(); $oPayout = new Payout();
$oPayout->setDebug($debug); $oPayout->setDebug($debug);
$oPayout->setLog($log);
$oPayout->setMysql($mysqli); $oPayout->setMysql($mysqli);
$oPayout->setConfig($config); $oPayout->setConfig($config);
$oPayout->setToken($oToken); $oPayout->setToken($oToken);

View File

@ -69,14 +69,23 @@ class User extends Base {
} }
public function changeNoFee($id) { public function changeNoFee($id) {
$field = array('name' => 'no_fees', 'type' => 'i', 'value' => !$this->isNoFee($id)); $field = array('name' => 'no_fees', 'type' => 'i', 'value' => !$this->isNoFee($id));
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogWarn($this->getUserName($id)." changed no_fees to ".$this->isNoFee($id)." from [".$_SERVER['REMOTE_ADDR']."]");
}
return $this->updateSingle($id, $field); return $this->updateSingle($id, $field);
} }
public function setLocked($id, $value) { public function setLocked($id, $value) {
$field = array('name' => 'is_locked', 'type' => 'i', 'value' => $value); $field = array('name' => 'is_locked', 'type' => 'i', 'value' => $value);
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogWarn($this->getUserName($id)." changed is_locked to $value from [".$_SERVER['REMOTE_ADDR']."]");
}
return $this->updateSingle($id, $field); return $this->updateSingle($id, $field);
} }
public function changeAdmin($id) { public function changeAdmin($id) {
$field = array('name' => 'is_admin', 'type' => 'i', 'value' => !$this->isAdmin($id)); $field = array('name' => 'is_admin', 'type' => 'i', 'value' => !$this->isAdmin($id));
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogWarn($this->getUserName($id)." changed is_admin to ".$this->isAdmin($id)." from [".$_SERVER['REMOTE_ADDR']."]");
}
return $this->updateSingle($id, $field); return $this->updateSingle($id, $field);
} }
public function setUserFailed($id, $value) { public function setUserFailed($id, $value) {
@ -145,6 +154,11 @@ class User extends Base {
$lastLoginTime = $this->getLastLogin($uid); $lastLoginTime = $this->getLastLogin($uid);
$this->updateLoginTimestamp($uid); $this->updateLoginTimestamp($uid);
$getIPAddress = $this->getUserIp($uid); $getIPAddress = $this->getUserIp($uid);
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
if ($getIPAddress !== $_SERVER['REMOTE_ADDR']) {
$this->log->LogWarn("$username has logged in with a different IP [".$_SERVER['REMOTE_ADDR']."] saved is [$getIPAddress]");
}
}
$setIPAddress = $this->setUserIp($uid, $_SERVER['REMOTE_ADDR']); $setIPAddress = $this->setUserIp($uid, $_SERVER['REMOTE_ADDR']);
$this->createSession($username, $getIPAddress, $lastLoginTime); $this->createSession($username, $getIPAddress, $lastLoginTime);
if ($setIPAddress) { if ($setIPAddress) {
@ -172,11 +186,17 @@ class User extends Base {
} }
} }
$this->setErrorMessage("Invalid username or password"); $this->setErrorMessage("Invalid username or password");
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogInfo("$username failed login from [".$_SERVER['REMOTE_ADDR']."]");
}
if ($id = $this->getUserId($username)) { if ($id = $this->getUserId($username)) {
$this->incUserFailed($id); $this->incUserFailed($id);
// Check if this account should be locked // Check if this account should be locked
if (isset($this->config['maxfailed']['login']) && $this->getUserFailed($id) >= $this->config['maxfailed']['login']) { if (isset($this->config['maxfailed']['login']) && $this->getUserFailed($id) >= $this->config['maxfailed']['login']) {
$this->setLocked($id, 1); $this->setLocked($id, 1);
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogWarn("$username locked via failed logins from [".$_SERVER['REMOTE_ADDR']."] saved is [".$this->getUserIp($this->getUserId($username))."]");
}
if ($token = $this->token->createToken('account_unlock', $id)) { if ($token = $this->token->createToken('account_unlock', $id)) {
$aData['token'] = $token; $aData['token'] = $token;
$aData['username'] = $username; $aData['username'] = $username;
@ -203,17 +223,23 @@ class User extends Base {
$pin_hash = $this->getHash($pin); $pin_hash = $this->getHash($pin);
if ($stmt->bind_param('is', $userId, $pin_hash) && $stmt->execute() && $stmt->bind_result($row_pin) && $stmt->fetch()) { if ($stmt->bind_param('is', $userId, $pin_hash) && $stmt->execute() && $stmt->bind_result($row_pin) && $stmt->fetch()) {
$this->setUserPinFailed($userId, 0); $this->setUserPinFailed($userId, 0);
return $pin_hash === $row_pin; return ($pin_hash === $row_pin);
}
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogInfo($this->getUserName($userId)." incorrect pin from [".$_SERVER['REMOTE_ADDR']."]");
} }
$this->incUserPinFailed($userId); $this->incUserPinFailed($userId);
// Check if this account should be locked // Check if this account should be locked
if (isset($this->config['maxfailed']['pin']) && $this->getUserPinFailed($userId) >= $this->config['maxfailed']['pin']) { if (isset($this->config['maxfailed']['pin']) && $this->getUserPinFailed($userId) >= $this->config['maxfailed']['pin']) {
$this->setLocked($userId, 1); $this->setLocked($userId, 1);
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogWarn($this->getUserName($userId)." was locked via incorrect pins from [".$_SERVER['REMOTE_ADDR']."]");
}
if ($token = $this->token->createToken('account_unlock', $userId)) { if ($token = $this->token->createToken('account_unlock', $userId)) {
$username = $this->getUserName($userId); $username = $this->getUserName($userId);
$aData['token'] = $token; $aData['token'] = $token;
$aData['username'] = $username; $aData['username'] = $username;
$aData['email'] = $this->getUserEmail($username);; $aData['email'] = $this->getUserEmail($username);
$aData['subject'] = 'Account auto-locked'; $aData['subject'] = 'Account auto-locked';
$this->mail->sendMail('notifications/locked', $aData); $this->mail->sendMail('notifications/locked', $aData);
} }
@ -234,17 +260,25 @@ class User extends Base {
$newpin = $this->getHash($newpin); $newpin = $this->getHash($newpin);
$aData['subject'] = 'PIN Reset Request'; $aData['subject'] = 'PIN Reset Request';
$stmt = $this->mysqli->prepare("UPDATE $this->table SET pin = ? WHERE ( id = ? AND pass = ? )"); $stmt = $this->mysqli->prepare("UPDATE $this->table SET pin = ? WHERE ( id = ? AND pass = ? )");
if ($this->checkStmt($stmt) && $stmt->bind_param('sis', $newpin, $userID, $current) && $stmt->execute()) { if ($this->checkStmt($stmt) && $stmt->bind_param('sis', $newpin, $userID, $current) && $stmt->execute()) {
if ($stmt->errno == 0 && $stmt->affected_rows === 1) { if ($stmt->errno == 0 && $stmt->affected_rows === 1) {
if ($this->mail->sendMail('pin/reset', $aData)) { if ($this->mail->sendMail('pin/reset', $aData)) {
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogInfo($this->getUserName($userID)." was sent a pin reset from [".$_SERVER['REMOTE_ADDR']."]");
}
return true; return true;
} else { } else {
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogWarn($this->getUserName($userID)." request a pin reset but the mailing failed from [".$_SERVER['REMOTE_ADDR']."]");
}
$this->setErrorMessage('Unable to send mail to your address'); $this->setErrorMessage('Unable to send mail to your address');
return false; return false;
} }
} }
} }
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogWarn($this->getUserName($userID)." incorrect pin reset attempt from [".$_SERVER['REMOTE_ADDR']."]");
}
$this->setErrorMessage( 'Unable to generate PIN, current password incorrect?' ); $this->setErrorMessage( 'Unable to generate PIN, current password incorrect?' );
return false; return false;
} }
@ -319,14 +353,23 @@ class User extends Base {
default: default:
$aData['subject'] = ''; $aData['subject'] = '';
} }
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogInfo($this->getUserName($userID)." was sent a $strType token from [".$_SERVER['REMOTE_ADDR']."]");
}
if ($this->mail->sendMail('notifications/'.$strType, $aData)) { if ($this->mail->sendMail('notifications/'.$strType, $aData)) {
return true; return true;
} else { } else {
$this->setErrorMessage('Failed to send the notification'); $this->setErrorMessage('Failed to send the notification');
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogWarn($this->getUserName($userID)." requested a $strType token but the mailing failed from [".$_SERVER['REMOTE_ADDR']."]");
}
return false; return false;
} }
} }
$this->setErrorMessage('A request has already been sent to your e-mail address. Please wait 10 minutes for it to expire.'); if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogWarn($this->getUserName($userID)." attempted to request multiple $strType tokens from [".$_SERVER['REMOTE_ADDR']."]");
}
$this->setErrorMessage('A request has already been sent to your e-mail address. Please wait an hour for it to expire.');
return false; return false;
} }
@ -351,25 +394,44 @@ class User extends Base {
} }
$current = $this->getHash($current); $current = $this->getHash($current);
$new = $this->getHash($new1); $new = $this->getHash($new1);
if ($this->config['twofactor']['enabled'] && $this->config['twofactor']['options']['changepw']) {
$tValid = $this->token->isTokenValid($userID, $strToken, 6);
if ($tValid) {
if ($this->token->deleteToken($strToken)) {
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogInfo($this->getUserName($userID)." deleted change password token from [".$_SERVER['REMOTE_ADDR']."]");
}
// token deleted, continue
} else {
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogWarn($this->getUserName($userID)." change password token failed to delete from [".$_SERVER['REMOTE_ADDR']."]");
}
$this->setErrorMessage('Token deletion failed');
return false;
}
} else {
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogWarn($this->getUserName($userID)." attempted to use an invalid change password token from [".$_SERVER['REMOTE_ADDR']."]");
}
$this->setErrorMessage('Invalid token');
return false;
}
}
$stmt = $this->mysqli->prepare("UPDATE $this->table SET pass = ? WHERE ( id = ? AND pass = ? )"); $stmt = $this->mysqli->prepare("UPDATE $this->table SET pass = ? WHERE ( id = ? AND pass = ? )");
if ($this->checkStmt($stmt)) { if ($this->checkStmt($stmt)) {
$stmt->bind_param('sis', $new, $userID, $current); $stmt->bind_param('sis', $new, $userID, $current);
$stmt->execute(); $stmt->execute();
if ($stmt->errno == 0 && $stmt->affected_rows === 1) { if ($stmt->errno == 0 && $stmt->affected_rows === 1) {
// twofactor - consume the token if it is enabled and valid if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
if ($this->config['twofactor']['enabled'] && $this->config['twofactor']['options']['changepw']) { $this->log->LogInfo($this->getUserName($userID)." updated password from [".$_SERVER['REMOTE_ADDR']."]");
$tValid = $this->token->isTokenValid($userID, $strToken, 6);
if ($tValid) {
$this->token->deleteToken($strToken);
} else {
$this->setErrorMessage('Invalid token');
return false;
}
} }
return true; return true;
} }
$stmt->close(); $stmt->close();
} }
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogWarn($this->getUserName($userID)." incorrect password update attempt from [".$_SERVER['REMOTE_ADDR']."]");
}
$this->setErrorMessage( 'Unable to update password, current password wrong?' ); $this->setErrorMessage( 'Unable to update password, current password wrong?' );
return false; return false;
} }
@ -434,20 +496,38 @@ class User extends Base {
$threshold = min($this->config['ap_threshold']['max'], max(0, floatval($threshold))); $threshold = min($this->config['ap_threshold']['max'], max(0, floatval($threshold)));
$donate = min(100, max(0, floatval($donate))); $donate = min(100, max(0, floatval($donate)));
// We passed all validation checks so update the account // twofactor - consume the token if it is enabled and valid
$stmt = $this->mysqli->prepare("UPDATE $this->table SET coin_address = ?, ap_threshold = ?, donate_percent = ?, email = ?, is_anonymous = ? WHERE id = ?"); if ($this->config['twofactor']['enabled'] && $this->config['twofactor']['options']['details']) {
if ($this->checkStmt($stmt) && $stmt->bind_param('sddsii', $address, $threshold, $donate, $email, $is_anonymous, $userID) && $stmt->execute()) $tValid = $this->token->isTokenValid($userID, $strToken, 5);
// twofactor - consume the token if it is enabled and valid if ($tValid) {
if ($this->config['twofactor']['enabled'] && $this->config['twofactor']['options']['details']) { if ($this->token->deleteToken($strToken)) {
$tValid = $this->token->isTokenValid($userID, $strToken, 5); if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
if ($tValid) { $this->log->LogInfo($this->getUserName($userID)." deleted account update token for [".$_SERVER['REMOTE_ADDR']."]");
$this->token->deleteToken($strToken); }
} else { } else {
$this->setErrorMessage('Invalid token'); $this->setErrorMessage('Token deletion failed');
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogWarn($this->getUserName($userID)." updated their account details but token deletion failed from [".$_SERVER['REMOTE_ADDR']."]");
}
return false; return false;
} }
} else {
$this->setErrorMessage('Invalid token');
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogWarn($this->getUserName($userID)." attempted to use an invalid token account update token from [".$_SERVER['REMOTE_ADDR']."]");
}
return false;
}
}
// We passed all validation checks so update the account
$stmt = $this->mysqli->prepare("UPDATE $this->table SET coin_address = ?, ap_threshold = ?, donate_percent = ?, email = ?, is_anonymous = ? WHERE id = ?");
if ($this->checkStmt($stmt) && $stmt->bind_param('sddsii', $address, $threshold, $donate, $email, $is_anonymous, $userID) && $stmt->execute()) {
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogInfo($this->getUserName($userID)." updated their account details from [".$_SERVER['REMOTE_ADDR']."]");
} }
return true; return true;
}
// Catchall // Catchall
$this->setErrorMessage('Failed to update your account'); $this->setErrorMessage('Failed to update your account');
$this->debug->append('Account update failed: ' . $this->mysqli->error); $this->debug->append('Account update failed: ' . $this->mysqli->error);
@ -542,7 +622,7 @@ class User extends Base {
$port = ($_SERVER["SERVER_PORT"] == "80" || $_SERVER["SERVER_PORT"] == "443") ? "" : (":".$_SERVER["SERVER_PORT"]); $port = ($_SERVER["SERVER_PORT"] == "80" || $_SERVER["SERVER_PORT"] == "443") ? "" : (":".$_SERVER["SERVER_PORT"]);
$pushto = $_SERVER['SCRIPT_NAME'].'?page=login'; $pushto = $_SERVER['SCRIPT_NAME'].'?page=login';
$location = (@$_SERVER['HTTPS'] == 'on') ? 'https://' . $_SERVER['SERVER_NAME'] . $port . $pushto : 'http://' . $_SERVER['SERVER_NAME'] . $port . $pushto; $location = (@$_SERVER['HTTPS'] == 'on') ? 'https://' . $_SERVER['SERVER_NAME'] . $port . $pushto : 'http://' . $_SERVER['SERVER_NAME'] . $port . $pushto;
// if (!headers_sent()) header('Location: ' . $location); if (!headers_sent()) header('Location: ' . $location);
exit('<meta http-equiv="refresh" content="0; url=' . $location . '"/>'); exit('<meta http-equiv="refresh" content="0; url=' . $location . '"/>');
} }
@ -789,6 +869,13 @@ class User extends Base {
} }
$aData['username'] = $this->getUserName($this->getUserId($username, true)); $aData['username'] = $this->getUserName($this->getUserId($username, true));
$aData['subject'] = 'Password Reset Request'; $aData['subject'] = 'Password Reset Request';
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
if ($_SERVER['REMOTE_ADDR'] !== $this->getUserIp($this->getUserId($username, true))) {
$this->log->LogWarn("$username requested password reset from [".$_SERVER['REMOTE_ADDR']."] saved is [".$this->getUserIp($this->getUserId($username, true))."]");
} else {
$this->log->LogInfo("$username requested password reset from [".$_SERVER['REMOTE_ADDR']."] saved is [".$this->getUserIp($this->getUserId($username, true))."]");
}
}
if ($this->mail->sendMail('password/reset', $aData)) { if ($this->mail->sendMail('password/reset', $aData)) {
return true; return true;
} else { } else {
@ -812,7 +899,10 @@ public function isAuthenticated($logout=true) {
$this->getUserIp($_SESSION['USERDATA']['id']) == $_SERVER['REMOTE_ADDR'] $this->getUserIp($_SESSION['USERDATA']['id']) == $_SERVER['REMOTE_ADDR']
) return true; ) return true;
// Catchall // Catchall
if ($logout == true) $this->logoutUser($_SERVER['REQUEST_URI']); if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$this->log->LogWarn("Forcing logout, user is locked or IP changed mid session from [".$_SERVER['REMOTE_ADDR']."]");
}
if ($logout == true) $this->logoutUser();
return false; return false;
} }
@ -853,6 +943,7 @@ public function isAuthenticated($logout=true) {
// Make our class available automatically // Make our class available automatically
$user = new User(); $user = new User();
$user->setDebug($debug); $user->setDebug($debug);
$user->setLog($log);
$user->setMysql($mysqli); $user->setMysql($mysqli);
$user->setSalt($config['SALT']); $user->setSalt($config['SALT']);
$user->setSmarty($smarty); $user->setSmarty($smarty);

View File

@ -9,6 +9,16 @@ $defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
$config['https_only'] = false; $config['https_only'] = false;
$config['mysql_filter'] = true; $config['mysql_filter'] = true;
/**
* Logging
* Log security issues - 0 = disabled, 2 = everything, 3 = warnings only
*
*/
$config['logging']['enabled'] = true;
$config['logging']['level'] = 3;
$config['logging']['path'] = realpath(BASEPATH.'../logs');
$config['logging']['file'] = date('Y-m-d').'.security.log';
/** /**
* Memcache Rate Limiting * Memcache Rate Limiting
* Rate limit requests using Memcache * Rate limit requests using Memcache

View File

@ -72,10 +72,10 @@ if ($user->isAuthenticated()) {
} }
} }
else { else {
if ( @$_POST['do'] && (!$checkpin = $user->checkPin($_SESSION['USERDATA']['id'], @$_POST['authPin']))) { if ( @$_POST['do'] && !$user->checkPin($_SESSION['USERDATA']['id'], @$_POST['authPin'])) {
$_SESSION['POPUP'][] = array('CONTENT' => 'Invalid PIN. ' . ($config['maxfailed']['pin'] - $user->getUserPinFailed($_SESSION['USERDATA']['id'])) . ' attempts remaining.', 'TYPE' => 'errormsg'); $_SESSION['POPUP'][] = array('CONTENT' => 'Invalid PIN. ' . ($config['maxfailed']['pin'] - $user->getUserPinFailed($_SESSION['USERDATA']['id'])) . ' attempts remaining.', 'TYPE' => 'errormsg');
} else { } else {
if (isset($_POST['unlock']) && isset($_POST['utype']) && $checkpin) { if (isset($_POST['unlock']) && isset($_POST['utype'])) {
$validtypes = array('account_edit','change_pw','withdraw_funds'); $validtypes = array('account_edit','change_pw','withdraw_funds');
$isvalid = in_array($_POST['utype'],$validtypes); $isvalid = in_array($_POST['utype'],$validtypes);
if ($isvalid) { if ($isvalid) {
@ -99,6 +99,9 @@ if ($user->isAuthenticated()) {
} else { } else {
$aBalance = $transaction->getBalance($_SESSION['USERDATA']['id']); $aBalance = $transaction->getBalance($_SESSION['USERDATA']['id']);
$dBalance = $aBalance['confirmed']; $dBalance = $aBalance['confirmed'];
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$user->log->LogInfo($_SESSION['USERDATA']['username']." requesting manual payout from [".$_SERVER['REMOTE_ADDR']."]");
}
if ($dBalance > $config['txfee_manual']) { if ($dBalance > $config['txfee_manual']) {
if (!$oPayout->isPayoutActive($_SESSION['USERDATA']['id'])) { if (!$oPayout->isPayoutActive($_SESSION['USERDATA']['id'])) {
if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) { if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) {

View File

@ -8,6 +8,9 @@ if (!$user->isAuthenticated() || !$user->isAdmin($_SESSION['USERDATA']['id'])) {
} }
if (@$_REQUEST['do'] == 'save' && !empty($_REQUEST['data'])) { if (@$_REQUEST['do'] == 'save' && !empty($_REQUEST['data'])) {
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$user->log->LogWarn($_SESSION['USERDATA']['username']." changed admin settings from [".$_SERVER['REMOTE_ADDR']."]");
}
foreach($_REQUEST['data'] as $var => $value) { foreach($_REQUEST['data'] as $var => $value) {
$setting->setValue($var, $value); $setting->setValue($var, $value);
} }

View File

@ -59,12 +59,14 @@ if ($config['memcache']['enabled'] && $config['mc_antidos']['enabled']) {
$session_start = @session_start(); $session_start = @session_start();
session_set_cookie_params(time()+$config['cookie']['duration'], $config['cookie']['path'], $config['cookie']['domain'], $config['cookie']['secure'], $config['cookie']['httponly']); session_set_cookie_params(time()+$config['cookie']['duration'], $config['cookie']['path'], $config['cookie']['domain'], $config['cookie']['secure'], $config['cookie']['httponly']);
if (!$session_start) { if (!$session_start) {
if ($this->config['logging']['enabled'] && $this->config['logging']['level'] > 0) {
$log->LogInfo("Forcing session id regeneration for ".$_SERVER['REMOTE_ADDR']." [hijack attempt?]");
}
session_destroy(); session_destroy();
session_regenerate_id(true); session_regenerate_id(true);
session_start(); session_start();
} }
@setcookie(session_name(), session_id(), time()+$config['cookie']['duration'], $config['cookie']['path'], $config['cookie']['domain'], $config['cookie']['secure'], $config['cookie']['httponly']); @setcookie(session_name(), session_id(), time()+$config['cookie']['duration'], $config['cookie']['path'], $config['cookie']['domain'], $config['cookie']['secure'], $config['cookie']['httponly']);
// Rate limiting // Rate limiting
if ($config['memcache']['enabled'] && $config['mc_antidos']['enabled']) { if ($config['memcache']['enabled'] && $config['mc_antidos']['enabled']) {
$skip_check = false; $skip_check = false;