[Auth] Prevent infinite sessions.

Prevents sessions from persisting beyond password changes.
This commit is contained in:
Kira 2021-12-18 03:36:19 -08:00
parent 40afaef933
commit fa6c9044cb
3 changed files with 15 additions and 4 deletions

View File

@ -16,11 +16,12 @@ class SessionCreator
user = User.find_by_name(name)
session[:user_id] = user.id
session[:ph] = user.password_token
user.update_column(:last_ip_addr, ip_addr)
if remember
verifier = ActiveSupport::MessageVerifier.new(Danbooru.config.remember_key, serializer: JSON, digest: "SHA256")
cookies.encrypted[:remember] = {value: verifier.generate(user.id, purpose: "rbr", expires_in: 14.days), expires: Time.now + 14.days, httponly: true, same_site: :lax, secure: Rails.env.production?}
cookies.encrypted[:remember] = {value: verifier.generate("#{user.id}:#{user.password_token}", purpose: "rbr", expires_in: 14.days), expires: Time.now + 14.days, httponly: true, same_site: :lax, secure: Rails.env.production?}
end
return true
else

View File

@ -60,18 +60,22 @@ private
begin
message = @remember_validator.verify(cookies.encrypted[:remember], purpose: "rbr")
return if message.nil?
user = User.find_by_id(message.to_i)
pieces = message.split(":")
return unless pieces.length == 2
user = User.find_by_id(pieces[0].to_i)
return unless user
return if pieces[1].to_i != user.password_token
CurrentUser.user = user
session[:user_id] = user.id
session[:ph] = user.password_token # This has been validated by the remember token
rescue
return
end
end
def refresh_old_remember_token
if cookies.encrypted[:remember]
cookies.encrypted[:remember] = {value: @remember_validator.generate(CurrentUser.id, purpose: "rbr", expires_in: 14.days), expires: Time.now + 14.days, httponly: true, same_site: :lax, secure: Rails.env.production?}
if cookies.encrypted[:remember] && !CurrentUser.is_anonymous?
cookies.encrypted[:remember] = {value: @remember_validator.generate("#{CurrentUser.id}:#{CurrentUser.password_token}", purpose: "rbr", expires_in: 14.days), expires: Time.now + 14.days, httponly: true, same_site: :lax, secure: Rails.env.production?}
end
end
@ -101,6 +105,7 @@ private
def load_session_user
user = User.find_by_id(session[:user_id])
return if session[:ph] != user.password_token
CurrentUser.user = user if user
end

View File

@ -1,4 +1,5 @@
require 'digest/sha1'
require 'zlib'
require 'danbooru/has_bit_flags'
class User < ApplicationRecord
@ -213,6 +214,10 @@ class User < ApplicationRecord
end
module PasswordMethods
def password_token
Zlib::crc32(bcrypt_password_hash)
end
def bcrypt_password
BCrypt::Password.new(bcrypt_password_hash)
end