summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBharat Mediratta <bharat@menalto.com>2010-02-02 21:48:01 -0800
committerBharat Mediratta <bharat@menalto.com>2010-02-02 21:48:01 -0800
commit99a7f470b93d35717f8d5979d05da6cf05a1dd20 (patch)
treeb6f9cd28d834ec665551909815658d65618b0aa1
parent6e1b761b12e13566875804c33efe2ae130ffa32e (diff)
Protect password changes against brute force attacks.
-rw-r--r--modules/gallery/helpers/auth.php10
-rw-r--r--modules/gallery/helpers/gallery_event.php12
-rw-r--r--modules/user/controllers/users.php12
3 files changed, 28 insertions, 6 deletions
diff --git a/modules/gallery/helpers/auth.php b/modules/gallery/helpers/auth.php
index 16f8915a..717cf40a 100644
--- a/modules/gallery/helpers/auth.php
+++ b/modules/gallery/helpers/auth.php
@@ -78,10 +78,16 @@ class auth_Core {
}
}
+ static function validate_too_many_failed_password_changes($password_input) {
+ if (self::too_many_failed_logins(identity::active_user()->name)) {
+ $password_input->add_error("too_many_failed_password_changes", 1);
+ }
+ }
+
/**
* Record a failed login for this user
*/
- static function record_failed_login($name) {
+ static function record_failed_auth_attempts($name) {
$failed_login = ORM::factory("failed_login")
->where("name", "=", $name)
->find();
@@ -96,7 +102,7 @@ class auth_Core {
/**
* Clear any failed logins for this user
*/
- static function record_successful_login($user) {
+ static function clear_failed_logins($user) {
db::build()
->delete("failed_logins")
->where("name", "=", $user->name)
diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php
index 6479e2c3..7b538c49 100644
--- a/modules/gallery/helpers/gallery_event.php
+++ b/modules/gallery/helpers/gallery_event.php
@@ -110,11 +110,19 @@ class gallery_event_Core {
graphics::choose_default_toolkit();
module::clear_var("gallery", "choose_default_tookit");
}
- auth::record_successful_login($user);
+ auth::clear_failed_auth_attempts($user);
}
static function user_login_failed($name) {
- auth::record_failed_login($name);
+ auth::record_failed_auth_attempts($name);
+ }
+
+ static function user_password_changed($user) {
+ auth::clear_failed_auth_attempts($user);
+ }
+
+ static function user_password_change_failed($name) {
+ auth::record_failed_auth_attempts($name);
}
static function item_index_data($item, $data) {
diff --git a/modules/user/controllers/users.php b/modules/user/controllers/users.php
index c11f22ff..166ff8b2 100644
--- a/modules/user/controllers/users.php
+++ b/modules/user/controllers/users.php
@@ -77,7 +77,7 @@ class Users_Controller extends Controller {
// Translate ORM validation errors into form error messages
foreach ($e->validation->errors() as $key => $error) {
$form->change_password->inputs[$key]->add_error($error, 1);
- }
+ }
$valid = false;
}
@@ -85,10 +85,14 @@ class Users_Controller extends Controller {
$user->save();
module::event("user_change_password_form_completed", $user, $form);
message::success(t("Password changed"));
+ module::event("user_password_change", $user);
print json_encode(
array("result" => "success",
"resource" => url::site("users/{$user->id}")));
} else {
+ log::warning("user", t("Failed password change for %name", array("name" => $user->name)));
+ $name = $user->name;
+ module::event("user_password_change_failed", $name);
print json_encode(array("result" => "error", "form" => (string) $form));
}
}
@@ -116,8 +120,12 @@ class Users_Controller extends Controller {
"users/change_password/$user->id", "", "post", array("id" => "g-change-password-user-form"));
$group = $form->group("change_password")->label(t("Change your password"));
$group->password("old_password")->label(t("Old password"))->id("g-password")
+ ->callback("auth::validate_too_many_failed_password_changes")
->callback("user::valid_password")
- ->error_messages("invalid", t("Incorrect password"));
+ ->error_messages("invalid", t("Incorrect password"))
+ ->error_messages(
+ "too_many_failed_password_changes",
+ t("Too many incorrect passwords. Try again later"));
$group->password("password")->label(t("New password"))->id("g-password")
->error_messages("min_length", t("Your new password is too short"));
$group->script("")