Skip to content

Commit

Permalink
Invalidate existing sessions when changing email or password
Browse files Browse the repository at this point in the history
As we don't have any way to actually find the active sessions for
an account we instead store a fingerprint in the session, and refuse
to use any session with a different fingerprint.
  • Loading branch information
tomhughes committed Sep 29, 2020
1 parent c694c78 commit 7db541d
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 1 deletion.
8 changes: 7 additions & 1 deletion app/controllers/application_controller.rb
Expand Up @@ -23,7 +23,11 @@ def authorize_web
if session[:user]
self.current_user = User.where(:id => session[:user]).where("status IN ('active', 'confirmed', 'suspended')").first

if current_user.status == "suspended"
if session[:fingerprint] &&
session[:fingerprint] != current_user.fingerprint
reset_session
self.current_user = nil
elsif current_user.status == "suspended"
session.delete(:user)
session_expires_automatically

Expand All @@ -42,6 +46,8 @@ def authorize_web
elsif session[:token]
session[:user] = current_user.id if self.current_user = User.authenticate(:token => session[:token])
end

session[:fingerprint] = current_user.fingerprint if current_user && session[:fingerprint].nil?
rescue StandardError => e
logger.info("Exception authorizing user: #{e}")
reset_session
Expand Down
6 changes: 6 additions & 0 deletions app/controllers/users_controller.rb
Expand Up @@ -183,6 +183,7 @@ def reset_password

if current_user.save
token.destroy
session[:fingerprint] = current_user.fingerprint
flash[:notice] = t "users.reset_password.flash changed"
successful_login(current_user)
end
Expand Down Expand Up @@ -323,6 +324,7 @@ def confirm
token.destroy

session[:user] = user.id
session[:fingerprint] = user.fingerprint

redirect_to referer || welcome_path
end
Expand Down Expand Up @@ -368,6 +370,7 @@ def confirm_email
end
current_user.tokens.delete_all
session[:user] = current_user.id
session[:fingerprint] = current_user.fingerprint
redirect_to :action => "account", :display_name => current_user.display_name
elsif token
flash[:error] = t "users.confirm_email.failure"
Expand Down Expand Up @@ -552,6 +555,7 @@ def openid_expand_url(openid_url)
# process a successful login
def successful_login(user, referer = nil)
session[:user] = user.id
session[:fingerprint] = user.fingerprint
session_expires_after 28.days if session[:remember_me]

target = referer || session[:referer] || url_for(:controller => :site, :action => :index)
Expand Down Expand Up @@ -642,6 +646,8 @@ def update_user(user, params)
end

if user.save
session[:fingerprint] = user.fingerprint

set_locale(true)

if user.new_email.blank? || user.new_email == user.email
Expand Down
8 changes: 8 additions & 0 deletions app/models/user.rb
Expand Up @@ -44,6 +44,7 @@
#

class User < ApplicationRecord
require "digest"
require "xml/libxml"

has_many :traces, -> { where(:visible => true) }
Expand Down Expand Up @@ -306,6 +307,13 @@ def access_token(application_key)
ClientApplication.find_by(:key => application_key).access_token_for_user(self)
end

def fingerprint
digest = Digest::SHA256.new
digest.update(email)
digest.update(pass_crypt)
digest.hexdigest
end

private

def set_defaults
Expand Down

0 comments on commit 7db541d

Please sign in to comment.