SECURITY: Limit name field length of TOTP authenticators and security keys

This commit is contained in:
OsamaSayegh
2023-08-24 09:27:38 +03:00
committed by Roman Rizzi
parent 85fddf58bc
commit c1b5faa5fd
21 changed files with 309 additions and 4 deletions

View File

@@ -96,6 +96,7 @@ class User < ActiveRecord::Base
has_many :directory_items
has_many :email_logs
has_many :security_keys, -> { where(enabled: true) }, class_name: "UserSecurityKey"
has_many :all_security_keys, class_name: "UserSecurityKey"
has_many :badges, through: :user_badges
has_many :default_featured_user_badges,

View File

@@ -2,6 +2,10 @@
class UserSecondFactor < ActiveRecord::Base
include SecondFactorManager
MAX_TOTPS_PER_USER = 50
MAX_NAME_LENGTH = 300
belongs_to :user
scope :backup_codes, -> { where(method: UserSecondFactor.methods[:backup_codes], enabled: true) }
@@ -10,6 +14,10 @@ class UserSecondFactor < ActiveRecord::Base
scope :all_totps, -> { where(method: UserSecondFactor.methods[:totp]) }
validates :name, length: { maximum: MAX_NAME_LENGTH }, if: :name_changed?
validate :count_per_user_does_not_exceed_limit, on: :create
def self.methods
@methods ||= Enum.new(totp: 1, backup_codes: 2, security_key: 3)
end
@@ -21,6 +29,16 @@ class UserSecondFactor < ActiveRecord::Base
def totp_provisioning_uri
totp_object.provisioning_uri(user.email)
end
private
def count_per_user_does_not_exceed_limit
if self.method == UserSecondFactor.methods[:totp]
if self.class.where(method: self.method, user_id: self.user_id).count >= MAX_TOTPS_PER_USER
errors.add(:base, I18n.t("login.too_many_authenticators"))
end
end
end
end
# == Schema Information
@@ -35,7 +53,7 @@ end
# last_used :datetime
# created_at :datetime not null
# updated_at :datetime not null
# name :string
# name :string(300)
#
# Indexes
#

View File

@@ -2,13 +2,26 @@
class UserSecurityKey < ActiveRecord::Base
belongs_to :user
MAX_KEYS_PER_USER = 50
MAX_NAME_LENGTH = 300
scope :second_factors,
-> { where(factor_type: UserSecurityKey.factor_types[:second_factor], enabled: true) }
validates :name, length: { maximum: MAX_NAME_LENGTH }, if: :name_changed?
validate :count_per_user_does_not_exceed_limit, on: :create
def self.factor_types
@factor_types ||= Enum.new(second_factor: 0, first_factor: 1, multi_factor: 2)
end
private
def count_per_user_does_not_exceed_limit
if UserSecurityKey.where(user_id: self.user_id).count >= MAX_KEYS_PER_USER
errors.add(:base, I18n.t("login.too_many_security_keys"))
end
end
end
# == Schema Information
@@ -21,7 +34,7 @@ end
# public_key :string not null
# factor_type :integer default(0), not null
# enabled :boolean default(TRUE), not null
# name :string not null
# name :string(300) not null
# last_used :datetime
# created_at :datetime not null
# updated_at :datetime not null