Class: Hooks::Plugins::Auth::SharedSecret
- Defined in:
- lib/hooks/plugins/auth/shared_secret.rb
Overview
This validator performs direct string comparison of the shared secret. While simpler than HMAC, it provides less security since the secret is transmitted directly in the request header.
Generic shared secret validator for webhooks
This validator provides simple shared secret authentication for webhook requests. It compares a secret value sent in a configurable HTTP header against the expected secret value. This is a common (though less secure than HMAC) authentication pattern used by various webhook providers.
Constant Summary collapse
- DEFAULT_CONFIG =
Default configuration values for shared secret validation
{ header: "Authorization" }.freeze
Constants inherited from Base
Base::MAX_HEADER_VALUE_LENGTH, Base::MAX_PAYLOAD_SIZE
Class Method Summary collapse
-
.valid?(payload:, headers:, config:) ⇒ Boolean
Validate shared secret from webhook requests.
Methods inherited from Base
fetch_secret, find_header_value, timestamp_validator, valid_header_value?, valid_headers?, valid_payload_size?
Methods included from Core::ComponentAccess
#failbot, #log, #method_missing, #respond_to_missing?, #stats
Class Method Details
.valid?(payload:, headers:, config:) ⇒ Boolean
This method is designed to be safe and will never raise exceptions
Uses Rack::Utils.secure_compare to prevent timing attacks
Validate shared secret from webhook requests
Performs secure comparison of the shared secret value from the configured header against the expected secret. Uses secure comparison to prevent timing attacks.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/hooks/plugins/auth/shared_secret.rb', line 59 def self.valid?(payload:, headers:, config:) secret = fetch_secret(config) validator_config = build_config(config) # Security: Check raw headers and payload BEFORE processing return false unless valid_headers?(headers) return false unless valid_payload_size?(payload) secret_header = validator_config[:header] # Find the secret header with case-insensitive matching provided_secret = find_header_value(headers, secret_header) if provided_secret.nil? || provided_secret.empty? log.warn("Auth::SharedSecret validation failed: Missing or empty secret header '#{secret_header}'") return false end # Validate secret format using shared validation unless valid_header_value?(provided_secret, "Secret") log.warn("Auth::SharedSecret validation failed: Invalid secret format") return false end # Use secure comparison to prevent timing attacks result = Rack::Utils.secure_compare(secret, provided_secret) if result log.debug("Auth::SharedSecret validation successful for header '#{secret_header}'") else log.warn("Auth::SharedSecret validation failed: Signature mismatch") end result rescue StandardError => e log.error("Auth::SharedSecret validation failed: #{e.}") false end |