1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Fix timing attack vulnerability in ActiveSupport::MessageVerifier.

Use a constant-time comparison algorithm to compare the candidate HMAC with the calculated HMAC to prevent leaking information about the calculated HMAC.

Signed-off-by: Michael Koziarski <michael@koziarski.com>
This commit is contained in:
Coda Hale 2009-08-13 10:03:08 -07:00 committed by Michael Koziarski
parent bd97c3044a
commit 5e6dab8b34

View file

@ -25,10 +25,10 @@ module ActiveSupport
def verify(signed_message) def verify(signed_message)
data, digest = signed_message.split("--") data, digest = signed_message.split("--")
if digest != generate_digest(data) if secure_compare(digest, generate_digest(data))
raise InvalidSignature
else
Marshal.load(ActiveSupport::Base64.decode64(data)) Marshal.load(ActiveSupport::Base64.decode64(data))
else
raise InvalidSignature
end end
end end
@ -38,6 +38,19 @@ module ActiveSupport
end end
private private
# constant-time comparison algorithm to prevent timing attacks
def secure_compare(a, b)
if a.length == b.length
result = 0
for i in 0..(a.length - 1)
result |= a[i] ^ b[i]
end
result == 0
else
false
end
end
def generate_digest(data) def generate_digest(data)
require 'openssl' unless defined?(OpenSSL) require 'openssl' unless defined?(OpenSSL)
OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new(@digest), @secret, data) OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new(@digest), @secret, data)