mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
SECURITY: Limit name field length of TOTP authenticators and security keys
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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
|
||||
#
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user