Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 75 lines (64 sloc) 2.353 kb
4f440a3 @lest fix base64 requires
lest authored
1 require 'active_support/base64'
f3e1b21 @marten Fix use of Deprecation without requiring active_support/deprecation i…
marten authored
2 require 'active_support/deprecation'
b7afaa0 @fxn message_verifier.rb needs active_support/core_ext/object/blank
fxn authored
3 require 'active_support/core_ext/object/blank'
679acfb @fxn message_verifier.rb needs active_support/base64
fxn authored
4
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tam…
NZKoz authored
5 module ActiveSupport
b99fb66 @suchasurge more style changes
suchasurge authored
6 # +MessageVerifier+ makes it easy to generate and verify messages which are signed
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tam…
NZKoz authored
7 # to prevent tampering.
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -ex…
spastorino authored
8 #
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tam…
NZKoz authored
9 # This is useful for cases like remember-me tokens and auto-unsubscribe links where the
10 # session store isn't suitable or available.
11 #
12 # Remember Me:
f9b1aa7 @NZKoz Don't need _message as it's in the class name already
NZKoz authored
13 # cookies[:remember_me] = @verifier.generate([@user.id, 2.weeks.from_now])
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -ex…
spastorino authored
14 #
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tam…
NZKoz authored
15 # In the authentication filter:
16 #
f9b1aa7 @NZKoz Don't need _message as it's in the class name already
NZKoz authored
17 # id, time = @verifier.verify(cookies[:remember_me])
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tam…
NZKoz authored
18 # if time < Time.now
19 # self.current_user = User.find(id)
20 # end
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -ex…
spastorino authored
21 #
2d30d4c @wvanbergen Add some documentation for the new serializer property of MessageVeri…
wvanbergen authored
22 # By default it uses Marshal to serialize the message. If you want to use another
23 # serialization method, you can set the serializer attribute to something that responds
24 # to dump and load, e.g.:
25 #
26 # @verifier.serializer = YAML
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tam…
NZKoz authored
27 class MessageVerifier
28 class InvalidSignature < StandardError; end
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -ex…
spastorino authored
29
41fea03 @wvanbergen Use an options hash to specify digest/cipher algorithm and a serializ…
wvanbergen authored
30 def initialize(secret, options = {})
31 unless options.is_a?(Hash)
b0ae34a @masterkain Fix typo in deprecation notice
masterkain authored
32 ActiveSupport::Deprecation.warn "The second parameter should be an options hash. Use :digest => 'algorithm' to specify the digest algorithm."
41fea03 @wvanbergen Use an options hash to specify digest/cipher algorithm and a serializ…
wvanbergen authored
33 options = { :digest => options }
34 end
35
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tam…
NZKoz authored
36 @secret = secret
41fea03 @wvanbergen Use an options hash to specify digest/cipher algorithm and a serializ…
wvanbergen authored
37 @digest = options[:digest] || 'SHA1'
38 @serializer = options[:serializer] || Marshal
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tam…
NZKoz authored
39 end
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -ex…
spastorino authored
40
f9b1aa7 @NZKoz Don't need _message as it's in the class name already
NZKoz authored
41 def verify(signed_message)
9212138 @packagethief MessageVerifier#verify raises InvalidSignature if the signature is blank
packagethief authored
42 raise InvalidSignature if signed_message.blank?
43
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tam…
NZKoz authored
44 data, digest = signed_message.split("--")
69aa5e8 @lifo Ensure MessageVerifier raises appropriate exception on tampered data
lifo authored
45 if data.present? && digest.present? && secure_compare(digest, generate_digest(data))
5f09414 @lest deprecate ActiveSupport::Base64
lest authored
46 @serializer.load(::Base64.decode64(data))
5e6dab8 @codahale Fix timing attack vulnerability in ActiveSupport::MessageVerifier.
codahale authored
47 else
48 raise InvalidSignature
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tam…
NZKoz authored
49 end
50 end
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -ex…
spastorino authored
51
f9b1aa7 @NZKoz Don't need _message as it's in the class name already
NZKoz authored
52 def generate(value)
5f09414 @lest deprecate ActiveSupport::Base64
lest authored
53 data = ::Base64.strict_encode64(@serializer.dump(value))
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tam…
NZKoz authored
54 "#{data}--#{generate_digest(data)}"
55 end
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -ex…
spastorino authored
56
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tam…
NZKoz authored
57 private
f959758 @tenderlove making secure_compare faster
tenderlove authored
58 # constant-time comparison algorithm to prevent timing attacks
59 def secure_compare(a, b)
60 return false unless a.bytesize == b.bytesize
a8a336c @wycats Revert "ruby 1.9 friendly secure_compare" because it breaks CI and Sa…
wycats authored
61
16bae77 @wycats Revert "Improve performance of MessageVerifier while keeping it const…
wycats authored
62 l = a.unpack "C#{a.bytesize}"
f959758 @tenderlove making secure_compare faster
tenderlove authored
63
16bae77 @wycats Revert "Improve performance of MessageVerifier while keeping it const…
wycats authored
64 res = 0
65 b.each_byte { |byte| res |= byte ^ l.shift }
66 res == 0
5e6dab8 @codahale Fix timing attack vulnerability in ActiveSupport::MessageVerifier.
codahale authored
67 end
68
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tam…
NZKoz authored
69 def generate_digest(data)
51d155e @jeremy Lazy-require OpenSSL
jeremy authored
70 require 'openssl' unless defined?(OpenSSL)
0a692e4 @jeremy Use OpenSSL::Digest.const(...).new instead of OpenSSL::Digest::Digest…
jeremy authored
71 OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get(@digest).new, @secret, data)
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tam…
NZKoz authored
72 end
73 end
51d155e @jeremy Lazy-require OpenSSL
jeremy authored
74 end
Something went wrong with that request. Please try again.