Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 69 lines (59 sloc) 2.092 kb
0f2f800 @lest remove ActiveSupport::Base64 in favor of ::Base64
lest authored
1 require 'base64'
b7afaa0 @fxn message_verifier.rb needs active_support/core_ext/object/blank
fxn authored
2 require 'active_support/core_ext/object/blank'
679acfb @fxn message_verifier.rb needs active_support/base64
fxn authored
3
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tamper...
NZKoz authored
4 module ActiveSupport
d71d5ba @frodsan update AS docs [ci skip]
frodsan authored
5 # +MessageVerifier+ makes it easy to generate and verify messages which are
6 # signed to prevent tampering.
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
7 #
d71d5ba @frodsan update AS docs [ci skip]
frodsan authored
8 # This is useful for cases like remember-me tokens and auto-unsubscribe links
019df98 @claudiob Replace comments' non-breaking spaces with spaces
claudiob authored
9 # where the session store isn't suitable or available.
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tamper...
NZKoz authored
10 #
11 # Remember Me:
f9b1aa7 @NZKoz Don't need _message as it's in the class name already
NZKoz authored
12 # cookies[:remember_me] = @verifier.generate([@user.id, 2.weeks.from_now])
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
13 #
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tamper...
NZKoz authored
14 # In the authentication filter:
15 #
f9b1aa7 @NZKoz Don't need _message as it's in the class name already
NZKoz authored
16 # id, time = @verifier.verify(cookies[:remember_me])
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tamper...
NZKoz authored
17 # if time < Time.now
18 # self.current_user = User.find(id)
19 # end
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
20 #
d71d5ba @frodsan update AS docs [ci skip]
frodsan authored
21 # By default it uses Marshal to serialize the message. If you want to use
0788d35 @docunext Updated docs due to removal of serializer accessor
docunext authored
22 # another serialization method, you can set the serializer in the options
23 # hash upon initialization:
2d30d4c @wvanbergen Add some documentation for the new serializer property of MessageVerifie...
wvanbergen authored
24 #
0788d35 @docunext Updated docs due to removal of serializer accessor
docunext authored
25 # @verifier = ActiveSupport::MessageVerifier.new('s3Krit', serializer: YAML)
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tamper...
NZKoz authored
26 class MessageVerifier
27 class InvalidSignature < StandardError; end
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
28
41fea03 @wvanbergen Use an options hash to specify digest/cipher algorithm and a serializer ...
wvanbergen authored
29 def initialize(secret, options = {})
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tamper...
NZKoz authored
30 @secret = secret
41fea03 @wvanbergen Use an options hash to specify digest/cipher algorithm and a serializer ...
wvanbergen authored
31 @digest = options[:digest] || 'SHA1'
32 @serializer = options[:serializer] || Marshal
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tamper...
NZKoz authored
33 end
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
34
f9b1aa7 @NZKoz Don't need _message as it's in the class name already
NZKoz authored
35 def verify(signed_message)
9212138 @packagethief MessageVerifier#verify raises InvalidSignature if the signature is blank
packagethief authored
36 raise InvalidSignature if signed_message.blank?
37
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tamper...
NZKoz authored
38 data, digest = signed_message.split("--")
69aa5e8 @lifo Ensure MessageVerifier raises appropriate exception on tampered data
lifo authored
39 if data.present? && digest.present? && secure_compare(digest, generate_digest(data))
0f2f800 @lest remove ActiveSupport::Base64 in favor of ::Base64
lest authored
40 @serializer.load(::Base64.decode64(data))
5e6dab8 @codahale Fix timing attack vulnerability in ActiveSupport::MessageVerifier.
codahale authored
41 else
42 raise InvalidSignature
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tamper...
NZKoz authored
43 end
44 end
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
45
f9b1aa7 @NZKoz Don't need _message as it's in the class name already
NZKoz authored
46 def generate(value)
0f2f800 @lest remove ActiveSupport::Base64 in favor of ::Base64
lest authored
47 data = ::Base64.strict_encode64(@serializer.dump(value))
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tamper...
NZKoz authored
48 "#{data}--#{generate_digest(data)}"
49 end
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
50
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tamper...
NZKoz authored
51 private
f959758 @tenderlove making secure_compare faster
tenderlove authored
52 # constant-time comparison algorithm to prevent timing attacks
53 def secure_compare(a, b)
54 return false unless a.bytesize == b.bytesize
a8a336c @wycats Revert "ruby 1.9 friendly secure_compare" because it breaks CI and Sam R...
wycats authored
55
16bae77 @wycats Revert "Improve performance of MessageVerifier while keeping it constant...
wycats authored
56 l = a.unpack "C#{a.bytesize}"
f959758 @tenderlove making secure_compare faster
tenderlove authored
57
16bae77 @wycats Revert "Improve performance of MessageVerifier while keeping it constant...
wycats authored
58 res = 0
59 b.each_byte { |byte| res |= byte ^ l.shift }
60 res == 0
5e6dab8 @codahale Fix timing attack vulnerability in ActiveSupport::MessageVerifier.
codahale authored
61 end
62
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tamper...
NZKoz authored
63 def generate_digest(data)
51d155e @jeremy Lazy-require OpenSSL
jeremy authored
64 require 'openssl' unless defined?(OpenSSL)
0a692e4 @jeremy Use OpenSSL::Digest.const(...).new instead of OpenSSL::Digest::Digest.ne...
jeremy authored
65 OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get(@digest).new, @secret, data)
d460c9a @NZKoz Add ActiveSupport::MessageVerifier to aid users who need to store tamper...
NZKoz authored
66 end
67 end
51d155e @jeremy Lazy-require OpenSSL
jeremy authored
68 end
Something went wrong with that request. Please try again.