Module: Stripe::Webhook::Signature

Defined in:
lib/stripe/webhook.rb

Constant Summary collapse

EXPECTED_SCHEME =
"v1".freeze

Class Method Summary collapse

Class Method Details

.verify_header(payload, header, secret, tolerance: nil) ⇒ Object

Verifies the signature header for a given payload.

Raises a SignatureVerificationError in the following cases:

  • the header does not match the expected format

  • no signatures found with the expected scheme

  • no signatures matching the expected signature

  • a tolerance is provided and the timestamp is not within the tolerance

Returns true otherwise



52
53
54
55
56
57
58
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
# File 'lib/stripe/webhook.rb', line 52

def self.verify_header(payload, header, secret, tolerance: nil)
  begin
    timestamp, signatures =
      get_timestamp_and_signatures(header, EXPECTED_SCHEME)
  rescue StandardError
    raise SignatureVerificationError.new(
      "Unable to extract timestamp and signatures from header",
      header, http_body: payload
    )
  end

  if signatures.empty?
    raise SignatureVerificationError.new(
      "No signatures found with expected scheme #{EXPECTED_SCHEME}",
      header, http_body: payload
    )
  end

  signed_payload = "#{timestamp}.#{payload}"
  expected_sig = compute_signature(signed_payload, secret)
  unless signatures.any? { |s| Util.secure_compare(expected_sig, s) }
    raise SignatureVerificationError.new(
      "No signatures found matching the expected signature for payload",
      header, http_body: payload
    )
  end

  if tolerance && timestamp < Time.now.to_f - tolerance
    raise SignatureVerificationError.new(
      "Timestamp outside the tolerance zone (#{Time.at(timestamp)})",
      header, http_body: payload
    )
  end

  true
end