Store only HMAC'd Auth codes, rather than plain text auth codes.

This commit is contained in:
Dan Milne
2025-12-31 15:00:00 +11:00
parent ed7ceedef5
commit 7c6ae7ab7e
3 changed files with 28 additions and 16 deletions

View File

@@ -2,6 +2,8 @@ class OidcAuthorizationCode < ApplicationRecord
belongs_to :application
belongs_to :user
attr_accessor :plaintext_code
before_validation :generate_code, on: :create
before_validation :set_expiry, on: :create
@@ -13,6 +15,19 @@ class OidcAuthorizationCode < ApplicationRecord
scope :valid, -> { where(used: false).where("expires_at > ?", Time.current) }
scope :expired, -> { where("expires_at <= ?", Time.current) }
# Find authorization code by plaintext code using HMAC verification
def self.find_by_plaintext(plaintext_code)
return nil if plaintext_code.blank?
code_hmac = compute_code_hmac(plaintext_code)
find_by(code: code_hmac)
end
# Compute HMAC for code lookup
def self.compute_code_hmac(plaintext_code)
OpenSSL::HMAC.hexdigest('SHA256', TokenHmac::KEY, plaintext_code)
end
def expired?
expires_at <= Time.current
end
@@ -32,7 +47,10 @@ class OidcAuthorizationCode < ApplicationRecord
private
def generate_code
self.code ||= SecureRandom.urlsafe_base64(32)
# Generate random plaintext code
self.plaintext_code ||= SecureRandom.urlsafe_base64(32)
# Store HMAC in database (not plaintext)
self.code ||= self.class.compute_code_hmac(plaintext_code)
end
def set_expiry