Web and web RPCs: add 5-second delay if password error

Slow down hackers trying to guess passwords
This commit is contained in:
David Anderson 2017-01-12 13:19:01 -08:00
parent 96ebcbff94
commit 06be40e8f0
3 changed files with 17 additions and 0 deletions

View File

@ -72,6 +72,11 @@ if (!defined('LDAP_HOST')) {
define('LDAP_HOST', null);
}
// sleep this long on any login failure
// (slow the rate of hacker attacks)
//
define('LOGIN_FAIL_SLEEP_SEC', 5);
$caching = false;
// if set, we're writing to a file rather than to client
$did_page_head = false;

View File

@ -36,6 +36,7 @@ check_get_args(array("id", "t", "h", "key"));
function login_with_email($email_addr, $passwd, $next_url, $perm) {
$user = BoincUser::lookup_email_addr($email_addr);
if (!$user) {
sleep(LOGIN_FAIL_SLEEP_SEC);
page_head("No such account");
echo "No account with email address <b>$email_addr</b> exists.
Please go back and try again.
@ -44,12 +45,14 @@ function login_with_email($email_addr, $passwd, $next_url, $perm) {
exit;
}
if (substr($user->authenticator, 0, 1) == 'x'){
sleep(LOGIN_FAIL_SLEEP_SEC);
error_page("This account has been administratively disabled.");
}
// allow authenticator as password
if ($passwd != $user->authenticator) {
$passwd_hash = md5($passwd.$email_addr);
if ($passwd_hash != $user->passwd_hash) {
sleep(LOGIN_FAIL_SLEEP_SEC);
page_head("Password incorrect");
echo "The password you entered is incorrect. Please go back and try again.\n";
page_tail();
@ -66,6 +69,7 @@ function login_with_email($email_addr, $passwd, $next_url, $perm) {
function login_via_link($id, $t, $h) {
$user = BoincUser::lookup_id($id);
if (!$user) {
sleep(LOGIN_FAIL_SLEEP_SEC);
error_page("Invalid user ID.
Please make sure you visited the complete URL;
it may have been split across lines by your email reader."
@ -75,12 +79,14 @@ function login_via_link($id, $t, $h) {
$x = md5($x);
$x = substr($x, 0, 16);
if ($x != $h) {
sleep(LOGIN_FAIL_SLEEP_SEC);
error_page("Invalid authenticator.
Please make sure you visited the complete URL;
it may have been split across lines by your email reader."
);
}
if (time() - $t > 86400) {
sleep(LOGIN_FAIL_SLEEP_SEC);
error_page("Link has expired;
go <a href=get_passwd.php>here</a> to
get a new login link by email."
@ -93,12 +99,14 @@ function login_via_link($id, $t, $h) {
function login_with_auth($authenticator, $next_url, $perm) {
$user = BoincUser::lookup_auth($authenticator);
if (!$user) {
sleep(LOGIN_FAIL_SLEEP_SEC);
page_head("Login failed");
echo "There is no account with that authenticator.
Please <a href=get_passwd.php>try again</a>.
";
page_tail();
} else if (substr($user->authenticator, 0, 1) == 'x'){
sleep(LOGIN_FAIL_SLEEP_SEC);
error_page("This account has been administratively disabled.");
} else {
Header("Location: $next_url");
@ -109,6 +117,7 @@ function login_with_auth($authenticator, $next_url, $perm) {
function login_with_ldap($uid, $passwd, $next_url, $perm) {
list ($ldap_user, $error_msg) = ldap_auth($uid, $passwd);
if ($error_msg) {
sleep(LOGIN_FAIL_SLEEP_SEC);
error_page($error_msg);
}
$x = ldap_email_string($uid);

View File

@ -37,6 +37,7 @@ if (LDAP_HOST && $ldap_auth) {
$passwd = get_str("passwd");
list ($ldap_user, $error_msg) = ldap_auth($ldap_uid, $passwd);
if ($error_msg) {
sleep(LOGIN_FAIL_SLEEP_SEC);
xml_error(ERR_BAD_USER_NAME, $error_msg);
}
$x = ldap_email_string($ldap_uid);
@ -55,6 +56,7 @@ if (LDAP_HOST && $ldap_auth) {
$email_addr = BoincDb::escape_string($email_addr);
$user = BoincUser::lookup("email_addr='$email_addr'");
if (!$user) {
sleep(LOGIN_FAIL_SLEEP_SEC);
xml_error(ERR_DB_NOT_FOUND);
}
@ -77,6 +79,7 @@ if (LDAP_HOST && $ldap_auth) {
// if the given password hash matches (auth+email), accept it
//
if ($user->passwd_hash != $passwd_hash && $auth_hash != $passwd_hash) {
sleep(LOGIN_FAIL_SLEEP_SEC);
xml_error(ERR_BAD_PASSWD);
}
}