about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2020-01-24 00:20:38 +0100
committerGitHub <noreply@github.com>2020-01-24 00:20:38 +0100
commitdaf71573d0e5f1376264c7d32cf55fae284ba9e5 (patch)
treefa467f25a0d842c4c5e6910dec1af7d18c217ce7
parentce1dee85b58fb7ab41af7ea1d276853630ce59a0 (diff)
Fix password change/reset not immediately invalidating other sessions (#12928)
While making browser requests in the other sessions after a password
change or reset does not allow you to be logged in and correctly
invalidates the session making the request, sessions have API tokens
associated with them, which can still be used until that session
is invalidated.

This is a security issue for accounts that were already compromised
some other way because it makes it harder to throw out the hijacker.
-rw-r--r--app/controllers/auth/passwords_controller.rb6
-rw-r--r--app/controllers/auth/registrations_controller.rb7
-rw-r--r--app/models/user.rb2
3 files changed, 14 insertions, 1 deletions
diff --git a/app/controllers/auth/passwords_controller.rb b/app/controllers/auth/passwords_controller.rb
index 34b98da53..b98bcecd0 100644
--- a/app/controllers/auth/passwords_controller.rb
+++ b/app/controllers/auth/passwords_controller.rb
@@ -6,6 +6,12 @@ class Auth::PasswordsController < Devise::PasswordsController
 
   layout 'auth'
 
+  def update
+    super do |resource|
+      resource.session_activations.destroy_all if resource.errors.empty?
+    end
+  end
+
   private
 
   def check_validity_of_reset_password_token
diff --git a/app/controllers/auth/registrations_controller.rb b/app/controllers/auth/registrations_controller.rb
index 212519c8b..745b91d46 100644
--- a/app/controllers/auth/registrations_controller.rb
+++ b/app/controllers/auth/registrations_controller.rb
@@ -22,10 +22,17 @@ class Auth::RegistrationsController < Devise::RegistrationsController
     not_found
   end
 
+  def update
+    super do |resource|
+      resource.clear_other_sessions(current_session.session_id) if resource.saved_change_to_encrypted_password?
+    end
+  end
+
   protected
 
   def update_resource(resource, params)
     params[:password] = nil if Devise.pam_authentication && resource.encrypted_password.blank?
+
     super
   end
 
diff --git a/app/models/user.rb b/app/models/user.rb
index a43e63b2e..058a8d5f8 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -247,7 +247,7 @@ class User < ApplicationRecord
                                  ip: request.remote_ip).session_id
   end
 
-  def exclusive_session(id)
+  def clear_other_sessions(id)
     session_activations.exclusive(id)
   end