This is a bit different from the challenge's script because it's directly copied from the issue.
# frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
gem "activesupport", "7.0.3"
end
require "active_support"
require "active_support/core_ext/object/blank"
require "minitest/autorun"
class BugTest < Minitest::Test
def test_stuff
old_secret = SecureRandom.base64(24)
old_encryptor = ActiveSupport::MessageEncryptor.new old_secret
current_secret = SecureRandom.base64(24)
current_encryptor = ActiveSupport::MessageEncryptor.new current_secret
current_encryptor.rotate old_secret
# Old encryptor roundtrips a 'nil' value correctly
assert_nil old_encryptor.decrypt_and_verify(old_encryptor.encrypt_and_sign(nil))
# New encryptor roundtrips a 'nil' value correctly
assert_nil current_encryptor.decrypt_and_verify(current_encryptor.encrypt_and_sign(nil))
# Old encryptor cannot decrypt data encrypted with the current secret
assert_raises(ActiveSupport::MessageVerifier::InvalidSignature) do
old_encryptor.decrypt_and_verify(current_encryptor.encrypt_and_sign("test"))
end
# New encryptor correctly decrypts data encrypted with the old secret (being rotated)
assert_equal "test", current_encryptor.decrypt_and_verify(old_encryptor.encrypt_and_sign("test"))
# New encryptor should be able to decrypt a 'nil' value encrypted with the old secret --THIS FAILS--
assert_nil current_encryptor.decrypt_and_verify(old_encryptor.encrypt_and_sign(nil))
end
end
def decrypt_and_verify(*args, on_rotation: @on_rotation, **options)
super
rescue MessageEncryptor::InvalidMessage, MessageVerifier::InvalidSignature
run_rotations(on_rotation) { |encryptor| encryptor.decrypt_and_verify(*args, **options) } || raise
end
- The initial decryption failed (the
super
call) and raised theMessageVerifier::InvalidSignature
exception - The exception was rescued, and it started to rotate the encryptors
- It rotated to an encryptor that has the old secret (added via
#rotate
). And it successfully decrypted the value asnil
- However, because this line uses
|| raise
, whenrun_rotations(on_rotation) { |encryptor| encryptor.decrypt_and_verify(*args, **options) }
returnednil
, it'd still re-raise the exception
I didn't have the 5 iterations constraint for myself when I started debugging the issue (was just finding a good debugging demo). So I was less stressful when doing it and that might have helped.
With that being said, I did force myself to finish it in a single session when I was in the 5th iteration. And it let me started using commands that I wasn't used to, like edit
and list -
. This experience inspired me to create the debugging challenge to see how constraints affect people's debugging behavior.
(I used ruby/debug in all 5 iterations)
From the test cases, I knew there are expected and unexpected exceptions. So I decided to trace exceptions and try to catch the InvalidSignature
ones with catch
breakpoints. But I started the tracer too early so it caused a lot of noise.
# I ran it with `rdbg -c -e "trace exception ;; c" ruby test.rb` to trace exceptions
# but because that activated tracers from the program start, it logged bundlers' exceptions as well
# and it caused a lot of noise so let's skip them here
DEBUGGER (trace/exception) #th:1 #depth:11 #<NameError: method `gem' not defined in #<Class:Kernel>
klass.send(:remove_method, method)
^^^^^> at ~/.gem/ruby/3.1.2/gems/bundler-2.3.7/lib/bundler/rubygems_integration.rb:415
DEBUGGER (trace/exception) #th:1 #depth:10 #<LoadError: cannot load such file -- activesupport> at ~/.gem/ruby/3.1.2/gems/bundler-2.3.7/lib/bundler/runtime.rb:60
DEBUGGER (trace/exception) #th:1 #depth:20 #<LoadError: cannot load such file -- concurrent/concurrent_ruby_ext> at ~/.gem/ruby/3.1.2/gems/concurrent-ruby-1.1.10/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb:62
DEBUGGER (trace/exception) #th:1 #depth:20 #<LoadError: cannot load such file -- concurrent/3.1/concurrent_ruby_ext> at ~/.gem/ruby/3.1.2/gems/concurrent-ruby-1.1.10/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb:62
Run options: --seed 29357
# Running:
[12, 21] in test.rb
12| require "active_support/core_ext/object/blank"
13| require "minitest/autorun"
14|
15| class BugTest < Minitest::Test
16| def test_stuff
=> 17| debugger(do: "catch ActiveSupport::MessageVerifier::InvalidSignature")
18| old_secret = SecureRandom.base64(24)
19| old_encryptor = ActiveSupport::MessageEncryptor.new old_secret
20|
21| current_secret = SecureRandom.base64(24)
=>#0 BugTest#test_stuff at test.rb:17
#1 block in run (3 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:98
# and 20 frames (use `bt' command for all frames)
(rdbg:binding.break) catch ActiveSupport::MessageVerifier::InvalidSignature
#0 BP - Catch "ActiveSupport::MessageVerifier::InvalidSignature"
DEBUGGER (trace/exception) #th:1 #depth:32 #<JSON::ParserError: 859: unexpected token at 'bZvGSU2UIMNUyG4LdgSSgg==--jObHmViZ8VEUfpR0r7w/aA=='> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:30 #<JSON::ParserError: 859: unexpected token at 0'> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:32 #<JSON::ParserError: 859: unexpected token at 'yHs2FzELtW7j5Hxd99JwA==--GlYfWlGUegUwEJmvd9uppQ=='> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:30 #<JSON::ParserError: 859: unexpected token at 0'> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
[173, 182] in ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb
173| # secret or was not Base64-encoded.
174| #
175| # other_verifier = ActiveSupport::MessageVerifier.new 'd1ff3r3nt-s3Krit'
176| # other_verifier.verify(signed_message) # => ActiveSupport::MessageVerifier::InvalidSignature
177| def verify(*args, **options)
=> 178| verified(*args, **options) || raise(InvalidSignature)
179| end
180|
181| # Generates a signed message for the provided value.
182| #
=>#0 ActiveSupport::MessageVerifier#verify(args=["NzY0RXZibnJaREFIL0o3WWcwYnY3UT09LS1rSkk..., options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178
#1 ActiveSupport::MessageEncryptor#decrypt_and_verify(data="NzY0RXZibnJaREFIL0o3WWcwYnY3UT09LS1rSkk3..., purpose=nil) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_encryptor.rb:160
# and 25 frames (use `bt' command for all frames)
Stop by #0 BP - Catch "ActiveSupport::MessageVerifier::InvalidSignature"
(rdbg) bt # backtrace command
=>#0 ActiveSupport::MessageVerifier#verify(args=["NzY0RXZibnJaREFIL0o3WWcwYnY3UT09LS1rSkk..., options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178
#1 ActiveSupport::MessageEncryptor#decrypt_and_verify(data="NzY0RXZibnJaREFIL0o3WWcwYnY3UT09LS1rSkk3..., purpose=nil) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_encryptor.rb:160
#2 ActiveSupport::Messages::Rotator::Encryptor#decrypt_and_verify(args=["NzY0RXZibnJaREFIL0o3WWcwYnY3UT09LS1rSkk..., on_rotation=nil, options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:22
#3 block in test_stuff at test.rb:33
#4 Minitest::Assertions#assert_raises(exp=[ActiveSupport::MessageVerifier::InvalidS...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/assertions.rb:404
#5 BugTest#test_stuff at test.rb:32
#6 block in run (3 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:98
#7 Minitest::Test#capture_exceptions at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:195
#8 block in run (2 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:95
#9 Minitest::Runnable#time_it at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:296
#10 block in run at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:94
#11 #<Class:Minitest::Runnable>#on_signal(name="INFO", action=#<Proc:0x000000010ea87708 /Users/hung-wul...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:391
#12 Minitest::Test#with_info_handler(block=#<Proc:0x000000010ea87898 /Users/hung-wul...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:243
#13 Minitest::Test#run at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:93
#14 Minitest.run_one_method(klass=BugTest, method_name="test_stuff") at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:1059
#15 #<Class:Minitest::Runnable>#run_one_method(klass=BugTest, method_name="test_stuff", reporter=#<Minitest::CompositeReporter:0x000000010...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:365
#16 block {|method_name="test_stuff"|} in run (2 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:352
#17 [C] Array#each at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:351
#18 block in run at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:351
#19 #<Class:Minitest::Runnable>#on_signal(name="INFO", action=#<Proc:0x000000010ea8e558 /Users/hung-wul...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:391
#20 #<Class:Minitest::Runnable>#with_info_handler(reporter=#<Minitest::CompositeReporter:0x000000010..., block=#<Proc:0x000000010ea8e9b8 /Users/hung-wul...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:378
#21 #<Class:Minitest::Runnable>#run(reporter=#<Minitest::CompositeReporter:0x000000010..., options={:io=>#<IO:<STDOUT>>, :seed=>29357, :args...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:350
#22 block {|suite=BugTest|} in __run at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:182
#23 [C] Array#map at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:182
#24 Minitest.__run(reporter=#<Minitest::CompositeReporter:0x000000010..., options={:io=>#<IO:<STDOUT>>, :seed=>29357, :args...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:182
#25 Minitest.run(args=[]) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:159
#26 block in autorun at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:83
(rdbg) c # continue command
DEBUGGER (trace/exception) #th:1 #depth:27 #<ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature> at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178
[19, 28] in ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb
19| include Rotator
20|
21| def decrypt_and_verify(*args, on_rotation: @on_rotation, **options)
22| super
23| rescue MessageEncryptor::InvalidMessage, MessageVerifier::InvalidSignature
=> 24| run_rotations(on_rotation) { |encryptor| encryptor.decrypt_and_verify(*args, **options) } || raise
25| end
26|
27| private
28| def build_rotation(secret = @secret, sign_secret = @sign_secret, options)
=>#0 ActiveSupport::Messages::Rotator::Encryptor#decrypt_and_verify at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:24
#1 ActiveSupport::Messages::Rotator::Encryptor#decrypt_and_verify(args=["NzY0RXZibnJaREFIL0o3WWcwYnY3UT09LS1rSkk..., on_rotation=nil, options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:21
# and 24 frames (use `bt' command for all frames)
Stop by #0 BP - Catch "ActiveSupport::MessageVerifier::InvalidSignature"
(rdbg) info # command
%self = #<ActiveSupport::MessageEncryptor:0x000000010ff3d1c0 @secret="VZejHjM6orIf/7U+OfVreWg2QKXb77in", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x000000010ff3ccc0 @secret="VZejHjM6orI...>
_raised = #<ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature>
args = ["NzY0RXZibnJaREFIL0o3WWcwYnY3UT09LS1rSkk3N1pydDJXVEhwQW0ralNEN1RBPT0=--735e3667437b456fe5f2c317d896c53d0793042e"]
on_rotation = nil
options = {}
@aead_mode = false
@cipher = "aes-256-cbc"
@digest = "SHA1"
@on_rotation = nil
@options = {}
@rotations = []
@secret = "VZejHjM6orIf/7U+OfVreWg2QKXb77in"
@serializer = Marshal
@sign_secret = nil
@verifier = #<ActiveSupport::MessageVerifier:0x000000010ff3ccc0 @secret="VZejHjM6orIf/7U+OfVreWg2QKXb77in", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer, @options={:digest=>"SHA1", :serializer=>ActiveSupport::MessageEncryptor::Null...>
(rdbg) q! # quit! command
E
Finished in 272.491107s, 0.0037 runs/s, 0.0147 assertions/s.
1) Error:
BugTest#test_stuff:
ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature
/Users/hung-wulo/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178:in `verify'
/Users/hung-wulo/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_encryptor.rb:160:in `decrypt_and_verify'
/Users/hung-wulo/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:22:in `decrypt_and_verify'
test.rb:40:in `test_stuff'
1 runs, 4 assertions, 0 failures, 1 errors, 0 skips
I placed the tracer correctly this time and poked around from both the library and the test case.
$ rdbg -c -n ruby test.rb
Fetching gem metadata from https://rubygems.org/........
Resolving dependencies...
Using bundler 2.3.7
Using concurrent-ruby 1.1.10
Using minitest 5.16.2
Using i18n 1.12.0
Using tzinfo 2.0.5
Using activesupport 7.0.3
Run options: --seed 64542
# Running:
[12, 21] in test.rb
12| require "active_support/core_ext/object/blank"
13| require "minitest/autorun"
14|
15| class BugTest < Minitest::Test
16| def test_stuff
=> 17| debugger(do: "trace exception ;; catch ActiveSupport::MessageVerifier::InvalidSignature")
18| old_secret = SecureRandom.base64(24)
19| old_encryptor = ActiveSupport::MessageEncryptor.new old_secret
20|
21| current_secret = SecureRandom.base64(24)
=>#0 BugTest#test_stuff at test.rb:17
#1 block in run (3 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:98
# and 20 frames (use `bt' command for all frames)
(rdbg:binding.break) trace exception
Enable ExceptionTracer (enabled)
(rdbg:binding.break) catch ActiveSupport::MessageVerifier::InvalidSignature
#0 BP - Catch "ActiveSupport::MessageVerifier::InvalidSignature"
[20, 29] in test.rb
20|
21| current_secret = SecureRandom.base64(24)
22| current_encryptor = ActiveSupport::MessageEncryptor.new current_secret
23| current_encryptor.rotate old_secret
24|
=> 25| debugger(do: "info")
26|
27| # Old encryptor roundtrips a 'nil' value correctly
28| assert_nil old_encryptor.decrypt_and_verify(old_encryptor.encrypt_and_sign(nil))
29|
=>#0 BugTest#test_stuff at test.rb:25
#1 block in run (3 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:98
# and 20 frames (use `bt' command for all frames)
(rdbg:binding.break) info
%self = #<BugTest:0x0000000112266070 @NAME="test_stuff", @assertions=0, @failures=[]>
old_secret = "6DCt7FGdeDdMHlCrODVos69R4tgbvIR2"
old_encryptor = #<ActiveSupport::MessageEncryptor:0x0000000112f7cfe8 @secret="6DCt7FGdeDdMHlCrODVos69R4tgbvIR2", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x0000000112f7c980 @secret="6DC...>
current_secret = "nn9lFwhrbSoVl2QlnLw5DyMDcZpr9phf"
current_encryptor = #<ActiveSupport::MessageEncryptor:0x0000000112f7c408 @secret="nn9lFwhrbSoVl2QlnLw5DyMDcZpr9phf", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x0000000112f7c188 @secret=...>
@NAME = "test_stuff"
@assertions = 0
@failures = []
DEBUGGER (trace/exception) #th:1 #depth:32 #<JSON::ParserError: 859: unexpected token at 'soGcijjcBXB1HrYr/lHlWg==--Gc6CL0oa0V+8mzUH4vy6KA=='> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:30 #<JSON::ParserError: 859: unexpected token at 0'> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:32 #<JSON::ParserError: 859: unexpected token at 'QeLf4JXO2rktfl0iNEt5w==--3D8bhxQltf+SeVYIdRpfmA=='> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:30 #<JSON::ParserError: 859: unexpected token at 0'> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
[173, 182] in ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb
173| # secret or was not Base64-encoded.
174| #
175| # other_verifier = ActiveSupport::MessageVerifier.new 'd1ff3r3nt-s3Krit'
176| # other_verifier.verify(signed_message) # => ActiveSupport::MessageVerifier::InvalidSignature
177| def verify(*args, **options)
=> 178| verified(*args, **options) || raise(InvalidSignature)
179| end
180|
181| # Generates a signed message for the provided value.
182| #
=>#0 ActiveSupport::MessageVerifier#verify(args=["MGx5RHJyRU9TclpLd0xITUkrVVVHdz09LS02VjZ..., options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178
#1 ActiveSupport::MessageEncryptor#decrypt_and_verify(data="MGx5RHJyRU9TclpLd0xITUkrVVVHdz09LS02VjZk..., purpose=nil) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_encryptor.rb:160
# and 25 frames (use `bt' command for all frames)
Stop by #0 BP - Catch "ActiveSupport::MessageVerifier::InvalidSignature"
(rdbg) q! # quit! command
E
Finished in 11.838025s, 0.0845 runs/s, 0.3379 assertions/s.
1) Error:
BugTest#test_stuff:
ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature
/Users/hung-wulo/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178:in `verify'
/Users/hung-wulo/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_encryptor.rb:160:in `decrypt_and_verify'
/Users/hung-wulo/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:22:in `decrypt_and_verify'
test.rb:42:in `test_stuff'
1 runs, 4 assertions, 0 failures, 1 errors, 0 skips
I tried to use something fancy like catch ActiveSupport::MessageVerifier::InvalidSignature do: "info"
and expected it to print frame info (variables) whenever a exception was raised. But I made a syntax mistake so it only printed "info"
instead of calling the info
command 🤦♂️ Basically wasted it.
$ rdbg -c -n ruby test.rb
Fetching gem metadata from https://rubygems.org/........
Resolving dependencies...
Using bundler 2.3.7
Using concurrent-ruby 1.1.10
Using minitest 5.16.2
Using i18n 1.12.0
Using tzinfo 2.0.5
Using activesupport 7.0.3
Run options: --seed 30132
# Running:
[12, 21] in test.rb
12| require "active_support/core_ext/object/blank"
13| require "minitest/autorun"
14|
15| class BugTest < Minitest::Test
16| def test_stuff
=> 17| debugger(do: "trace exception ;; catch ActiveSupport::MessageVerifier::InvalidSignature do: 'info'")
18| old_secret = SecureRandom.base64(24)
19| old_encryptor = ActiveSupport::MessageEncryptor.new old_secret
20|
21| current_secret = SecureRandom.base64(24)
=>#0 BugTest#test_stuff at test.rb:17
#1 block in run (3 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:98
# and 20 frames (use `bt' command for all frames)
(rdbg:binding.break) trace exception
Enable ExceptionTracer (enabled)
(rdbg:binding.break) catch ActiveSupport::MessageVerifier::InvalidSignature do: 'info'
#0 BP - Catch "ActiveSupport::MessageVerifier::InvalidSignature"
[20, 29] in test.rb
20|
21| current_secret = SecureRandom.base64(24)
22| current_encryptor = ActiveSupport::MessageEncryptor.new current_secret
23| current_encryptor.rotate old_secret
24|
=> 25| debugger(do: "info")
26|
27| # Old encryptor roundtrips a 'nil' value correctly
28| assert_nil old_encryptor.decrypt_and_verify(old_encryptor.encrypt_and_sign(nil))
29|
=>#0 BugTest#test_stuff at test.rb:25
#1 block in run (3 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:98
# and 20 frames (use `bt' command for all frames)
(rdbg:binding.break) info
%self = #<BugTest:0x000000011871d6a8 @NAME="test_stuff", @assertions=0, @failures=[]>
old_secret = "e6KxH42DKJyQbcb4Q/X2QcCzQyjjsAeW"
old_encryptor = #<ActiveSupport::MessageEncryptor:0x0000000119386d68 @secret="e6KxH42DKJyQbcb4Q/X2QcCzQyjjsAeW", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x00000001193867a0 @secret="e6K...>
current_secret = "BPD80Kq/RvEDBc/LKlPcLkncZnGHxGLQ"
current_encryptor = #<ActiveSupport::MessageEncryptor:0x00000001193862f0 @secret="BPD80Kq/RvEDBc/LKlPcLkncZnGHxGLQ", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x0000000119386098 @secret=...>
@NAME = "test_stuff"
@assertions = 0
@failures = []
DEBUGGER (trace/exception) #th:1 #depth:32 #<JSON::ParserError: 859: unexpected token at 't0RxJFWqsMe15FxRz48FYg==--ohmjSZMsdEq6tqGZUMBHqA=='> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:30 #<JSON::ParserError: 859: unexpected token at 0'> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:32 #<JSON::ParserError: 859: unexpected token at 'Xxaz04nV3duyaj5sfb4sVQ==--YJPiUsVzPPI9Aqamfa8OpQ=='> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:30 #<JSON::ParserError: 859: unexpected token at 0'> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
[173, 182] in ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb
173| # secret or was not Base64-encoded.
174| #
175| # other_verifier = ActiveSupport::MessageVerifier.new 'd1ff3r3nt-s3Krit'
176| # other_verifier.verify(signed_message) # => ActiveSupport::MessageVerifier::InvalidSignature
177| def verify(*args, **options)
=> 178| verified(*args, **options) || raise(InvalidSignature)
179| end
180|
181| # Generates a signed message for the provided value.
182| #
=>#0 ActiveSupport::MessageVerifier#verify(args=["V3lOZG1wUUJOVndvNjR5enVDU0U2Zz09LS0zY2Z..., options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178
#1 ActiveSupport::MessageEncryptor#decrypt_and_verify(data="V3lOZG1wUUJOVndvNjR5enVDU0U2Zz09LS0zY2ZB..., purpose=nil) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_encryptor.rb:160
# and 25 frames (use `bt' command for all frames)
Stop by #0 BP - Catch "ActiveSupport::MessageVerifier::InvalidSignature"
(rdbg:catch) 'info'
"info"
DEBUGGER (trace/exception) #th:1 #depth:27 #<ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature> at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178
[19, 28] in ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb
19| include Rotator
20|
21| def decrypt_and_verify(*args, on_rotation: @on_rotation, **options)
22| super
23| rescue MessageEncryptor::InvalidMessage, MessageVerifier::InvalidSignature
=> 24| run_rotations(on_rotation) { |encryptor| encryptor.decrypt_and_verify(*args, **options) } || raise
25| end
26|
27| private
28| def build_rotation(secret = @secret, sign_secret = @sign_secret, options)
=>#0 ActiveSupport::Messages::Rotator::Encryptor#decrypt_and_verify at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:24
#1 ActiveSupport::Messages::Rotator::Encryptor#decrypt_and_verify(args=["V3lOZG1wUUJOVndvNjR5enVDU0U2Zz09LS0zY2Z..., on_rotation=nil, options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:21
# and 24 frames (use `bt' command for all frames)
Stop by #0 BP - Catch "ActiveSupport::MessageVerifier::InvalidSignature"
(rdbg:catch) 'info'
"info"
DEBUGGER (trace/exception) #th:1 #depth:26 #<ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature> at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:24
[173, 182] in ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb
173| # secret or was not Base64-encoded.
174| #
175| # other_verifier = ActiveSupport::MessageVerifier.new 'd1ff3r3nt-s3Krit'
176| # other_verifier.verify(signed_message) # => ActiveSupport::MessageVerifier::InvalidSignature
177| def verify(*args, **options)
=> 178| verified(*args, **options) || raise(InvalidSignature)
179| end
180|
181| # Generates a signed message for the provided value.
182| #
=>#0 ActiveSupport::MessageVerifier#verify(args=["b3NEMkxuMnN5d1YvYXJ0NlRNcGxMQT09LS0rZFZ..., options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178
#1 ActiveSupport::MessageEncryptor#decrypt_and_verify(data="b3NEMkxuMnN5d1YvYXJ0NlRNcGxMQT09LS0rZFZl..., purpose=nil) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_encryptor.rb:160
# and 23 frames (use `bt' command for all frames)
Stop by #0 BP - Catch "ActiveSupport::MessageVerifier::InvalidSignature"
(rdbg:catch) 'info'
"info"
DEBUGGER (trace/exception) #th:1 #depth:25 #<ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature> at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178
DEBUGGER (trace/exception) #th:1 #depth:39 #<JSON::ParserError: 859: unexpected token at 'osD2Ln2sywV/art6TMplLA==--+dVeL3a8mJchsI/2KfzmYg=='> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:37 #<JSON::ParserError: 859: unexpected token at I" test:ET'> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
[173, 182] in ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb
173| # secret or was not Base64-encoded.
174| #
175| # other_verifier = ActiveSupport::MessageVerifier.new 'd1ff3r3nt-s3Krit'
176| # other_verifier.verify(signed_message) # => ActiveSupport::MessageVerifier::InvalidSignature
177| def verify(*args, **options)
=> 178| verified(*args, **options) || raise(InvalidSignature)
179| end
180|
181| # Generates a signed message for the provided value.
182| #
=>#0 ActiveSupport::MessageVerifier#verify(args=["cW1CUXJiQmhoRkFJUVpibU5rOU5yZz09LS1zMmF..., options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178
#1 ActiveSupport::MessageEncryptor#decrypt_and_verify(data="cW1CUXJiQmhoRkFJUVpibU5rOU5yZz09LS1zMmFM..., purpose=nil) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_encryptor.rb:160
# and 23 frames (use `bt' command for all frames)
Stop by #0 BP - Catch "ActiveSupport::MessageVerifier::InvalidSignature"
(rdbg:catch) 'info'
"info"
DEBUGGER (trace/exception) #th:1 #depth:25 #<ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature> at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178
DEBUGGER (trace/exception) #th:1 #depth:39 #<JSON::ParserError: 859: unexpected token at 'qmBQrbBhhFAIQZbmNk9Nrg==--s2aLbEuVmjp8byWFx1irtg=='> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:37 #<JSON::ParserError: 859: unexpected token at 0'> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
[19, 28] in ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb
19| include Rotator
20|
21| def decrypt_and_verify(*args, on_rotation: @on_rotation, **options)
22| super
23| rescue MessageEncryptor::InvalidMessage, MessageVerifier::InvalidSignature
=> 24| run_rotations(on_rotation) { |encryptor| encryptor.decrypt_and_verify(*args, **options) } || raise
25| end
26|
27| private
28| def build_rotation(secret = @secret, sign_secret = @sign_secret, options)
=>#0 ActiveSupport::Messages::Rotator::Encryptor#decrypt_and_verify at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:24
#1 ActiveSupport::Messages::Rotator::Encryptor#decrypt_and_verify(args=["cW1CUXJiQmhoRkFJUVpibU5rOU5yZz09LS1zMmF..., on_rotation=nil, options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:21
# and 22 frames (use `bt' command for all frames)
Stop by #0 BP - Catch "ActiveSupport::MessageVerifier::InvalidSignature"
(rdbg:catch) 'info'
"info"
DEBUGGER (trace/exception) #th:1 #depth:24 #<ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature> at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:24
E
Finished in 0.128255s, 7.7970 runs/s, 31.1879 assertions/s.
1) Error:
BugTest#test_stuff:
ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature
/Users/hung-wulo/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178:in `verify'
/Users/hung-wulo/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_encryptor.rb:160:in `decrypt_and_verify'
/Users/hung-wulo/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:22:in `decrypt_and_verify'
test.rb:42:in `test_stuff'
1 runs, 4 assertions, 0 failures, 1 errors, 0 skips
DEBUGGER (trace/exception) #th:1 #depth:2 #<SystemExit: exit> at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:80
Not sure what I was doing here.
$ rdbg -c -n ruby test.rb
Fetching gem metadata from https://rubygems.org/........
Resolving dependencies...
Using minitest 5.16.2
Using concurrent-ruby 1.1.10
Using bundler 2.3.7
Using tzinfo 2.0.5
Using i18n 1.12.0
Using activesupport 7.0.3
Run options: --seed 63351
# Running:
[12, 21] in test.rb
12| require "active_support/core_ext/object/blank"
13| require "minitest/autorun"
14|
15| class BugTest < Minitest::Test
16| def test_stuff
=> 17| debugger(do: "trace exception ;; catch ActiveSupport::MessageVerifier::InvalidSignature pre: 'info'")
18| old_secret = SecureRandom.base64(24)
19| old_encryptor = ActiveSupport::MessageEncryptor.new old_secret
20|
21| current_secret = SecureRandom.base64(24)
=>#0 BugTest#test_stuff at test.rb:17
#1 block in run (3 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:98
# and 20 frames (use `bt' command for all frames)
(rdbg:binding.break) trace exception
Enable ExceptionTracer (enabled)
(rdbg:binding.break) catch ActiveSupport::MessageVerifier::InvalidSignature pre: 'info'
#0 BP - Catch "ActiveSupport::MessageVerifier::InvalidSignature"
[20, 29] in test.rb
20|
21| current_secret = SecureRandom.base64(24)
22| current_encryptor = ActiveSupport::MessageEncryptor.new current_secret
23| current_encryptor.rotate old_secret
24|
=> 25| debugger(do: "info")
26|
27| # Old encryptor roundtrips a 'nil' value correctly
28| assert_nil old_encryptor.decrypt_and_verify(old_encryptor.encrypt_and_sign(nil))
29|
=>#0 BugTest#test_stuff at test.rb:25
#1 block in run (3 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:98
# and 20 frames (use `bt' command for all frames)
(rdbg:binding.break) info
%self = #<BugTest:0x000000010b60eb48 @NAME="test_stuff", @assertions=0, @failures=[]>
old_secret = "XoX8wqb/f/nlfOu5L4SDaHL6LX5Gx/wK"
old_encryptor = #<ActiveSupport::MessageEncryptor:0x000000010c18dca8 @secret="XoX8wqb/f/nlfOu5L4SDaHL6LX5Gx/wK", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x000000010c18d140 @secret="XoX...>
current_secret = "yupETd36cNKzrzVswzpQ4xDlJwgzVnS2"
current_encryptor = #<ActiveSupport::MessageEncryptor:0x000000010c18c358 @secret="yupETd36cNKzrzVswzpQ4xDlJwgzVnS2", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x000000010c18c060 @secret=...>
@NAME = "test_stuff"
@assertions = 0
@failures = []
DEBUGGER (trace/exception) #th:1 #depth:32 #<JSON::ParserError: 859: unexpected token at 'oeoYX1rTLjjS++8AKsKuUw==--vs2dWX5MouabmQbM4Rj4Lw=='> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:30 #<JSON::ParserError: 859: unexpected token at 0'> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:32 #<JSON::ParserError: 859: unexpected token at 'TPgGb+L2BOcsK5lxS0G+NQ==--eCl6WejwM04gvLQ8/suoQA=='> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:30 #<JSON::ParserError: 859: unexpected token at 0'> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
[173, 182] in ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb
173| # secret or was not Base64-encoded.
174| #
175| # other_verifier = ActiveSupport::MessageVerifier.new 'd1ff3r3nt-s3Krit'
176| # other_verifier.verify(signed_message) # => ActiveSupport::MessageVerifier::InvalidSignature
177| def verify(*args, **options)
=> 178| verified(*args, **options) || raise(InvalidSignature)
179| end
180|
181| # Generates a signed message for the provided value.
182| #
=>#0 ActiveSupport::MessageVerifier#verify(args=["T3YvUU5nYTlvemVxZzBlTFR0Z0lZdz09LS1mUEF..., options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178
#1 ActiveSupport::MessageEncryptor#decrypt_and_verify(data="T3YvUU5nYTlvemVxZzBlTFR0Z0lZdz09LS1mUEFs..., purpose=nil) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_encryptor.rb:160
# and 25 frames (use `bt' command for all frames)
Stop by #0 BP - Catch "ActiveSupport::MessageVerifier::InvalidSignature"
(rdbg:catch) 'info'
"info"
(rdbg) q! # quit! command
E
Finished in 13.817523s, 0.0724 runs/s, 0.2895 assertions/s.
1) Error:
BugTest#test_stuff:
ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature
/Users/hung-wulo/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178:in `verify'
/Users/hung-wulo/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_encryptor.rb:160:in `decrypt_and_verify'
/Users/hung-wulo/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:22:in `decrypt_and_verify'
test.rb:42:in `test_stuff'
1 runs, 4 assertions, 0 failures, 1 errors, 0 skips
I decided to locate the cause in this iteration no matter what happens. So I treid a lot of stuff here:
step
andnext
to slowly advance (cause no going backward)up
anddown
to move between framesinfo
andls
to collect informationlist
to print source code (which advances everytime is called, so I also usedlist -
to move back)edit
to openActiveSupport
in editor
$ rdbg -c -n ruby test.rb
Fetching gem metadata from https://rubygems.org/........
Resolving dependencies...
Using concurrent-ruby 1.1.10
Using bundler 2.3.7
Using minitest 5.16.2
Using i18n 1.12.0
Using tzinfo 2.0.5
Using activesupport 7.0.3
Run options: --seed 37767
# Running:
[12, 21] in test.rb
12| require "active_support/core_ext/object/blank"
13| require "minitest/autorun"
14|
15| class BugTest < Minitest::Test
16| def test_stuff
=> 17| debugger(do: "trace exception ;; catch ActiveSupport::MessageVerifier::InvalidSignature pre: info")
18| old_secret = SecureRandom.base64(24)
19| old_encryptor = ActiveSupport::MessageEncryptor.new old_secret
20|
21| current_secret = SecureRandom.base64(24)
=>#0 BugTest#test_stuff at test.rb:17
#1 block in run (3 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:98
# and 20 frames (use `bt' command for all frames)
(rdbg:binding.break) trace exception
Enable ExceptionTracer (enabled)
(rdbg:binding.break) catch ActiveSupport::MessageVerifier::InvalidSignature pre: info
#0 BP - Catch "ActiveSupport::MessageVerifier::InvalidSignature"
[20, 29] in test.rb
20|
21| current_secret = SecureRandom.base64(24)
22| current_encryptor = ActiveSupport::MessageEncryptor.new current_secret
23| current_encryptor.rotate old_secret
24|
=> 25| debugger(do: "info")
26|
27| # Old encryptor roundtrips a 'nil' value correctly
28| assert_nil old_encryptor.decrypt_and_verify(old_encryptor.encrypt_and_sign(nil))
29|
=>#0 BugTest#test_stuff at test.rb:25
#1 block in run (3 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:98
# and 20 frames (use `bt' command for all frames)
(rdbg:binding.break) info
%self = #<BugTest:0x000000011105d7e8 @NAME="test_stuff", @assertions=0, @failures=[]>
old_secret = "RNQ2YepodsSZzyk7cmXLjATDycy1K9WA"
old_encryptor = #<ActiveSupport::MessageEncryptor:0x0000000111d77078 @secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x0000000111d76ad8 @secret="RNQ...>
current_secret = "MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE"
current_encryptor = #<ActiveSupport::MessageEncryptor:0x0000000111d76650 @secret="MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x0000000111d763f8 @secret=...>
@NAME = "test_stuff"
@assertions = 0
@failures = []
DEBUGGER (trace/exception) #th:1 #depth:32 #<JSON::ParserError: 859: unexpected token at 'bVs6qzIakT3D+wJmwtPEbg==--hk2jIJ2jaF6QLuY7sKgolg=='> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:30 #<JSON::ParserError: 859: unexpected token at 0'> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:32 #<JSON::ParserError: 859: unexpected token at 'oF+BZ1q6Y4jezWH6uwzd9Q==--E4IuCqU3UaRlsyM73xEbHw=='> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:30 #<JSON::ParserError: 859: unexpected token at 0'> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
[173, 182] in ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb
173| # secret or was not Base64-encoded.
174| #
175| # other_verifier = ActiveSupport::MessageVerifier.new 'd1ff3r3nt-s3Krit'
176| # other_verifier.verify(signed_message) # => ActiveSupport::MessageVerifier::InvalidSignature
177| def verify(*args, **options)
=> 178| verified(*args, **options) || raise(InvalidSignature)
179| end
180|
181| # Generates a signed message for the provided value.
182| #
=>#0 ActiveSupport::MessageVerifier#verify(args=["RjArNFZBR1VEOGYyQzkwY0ZyRTBTQT09LS1ncVM..., options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178
#1 ActiveSupport::MessageEncryptor#decrypt_and_verify(data="RjArNFZBR1VEOGYyQzkwY0ZyRTBTQT09LS1ncVM2..., purpose=nil) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_encryptor.rb:160
# and 25 frames (use `bt' command for all frames)
Stop by #0 BP - Catch "ActiveSupport::MessageVerifier::InvalidSignature"
(rdbg:catch) info
%self = #<ActiveSupport::MessageVerifier:0x0000000111d76ad8 @secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer, @options={:digest=>"SHA1", :serializer=>ActiveSupport::MessageEncryptor::NullSeri...>
_raised = #<ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature>
args = ["RjArNFZBR1VEOGYyQzkwY0ZyRTBTQT09LS1ncVM2UlNFNW9XYlRqS0pMV0F5ekJBPT0=--c994dbb5b1bc397e7b3c8ba68636633b652864a8"]
options = {}
@digest = "SHA1"
@digest_length_in_hex = 40
@on_rotation = nil
@options = {:digest=>"SHA1", :serializer=>ActiveSupport::MessageEncryptor::NullSerializer}
@rotations = []
@secret = "RNQ2YepodsSZzyk7cmXLjATDycy1K9WA"
@serializer = ActiveSupport::MessageEncryptor::NullSerializer
(rdbg) bt 10 # backtrace command
=>#0 ActiveSupport::MessageVerifier#verify(args=["RjArNFZBR1VEOGYyQzkwY0ZyRTBTQT09LS1ncVM..., options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178
#1 ActiveSupport::MessageEncryptor#decrypt_and_verify(data="RjArNFZBR1VEOGYyQzkwY0ZyRTBTQT09LS1ncVM2..., purpose=nil) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_encryptor.rb:160
#2 ActiveSupport::Messages::Rotator::Encryptor#decrypt_and_verify(args=["RjArNFZBR1VEOGYyQzkwY0ZyRTBTQT09LS1ncVM..., on_rotation=nil, options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:22
#3 block in test_stuff at test.rb:35
#4 Minitest::Assertions#assert_raises(exp=[ActiveSupport::MessageVerifier::InvalidS...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/assertions.rb:404
#5 BugTest#test_stuff at test.rb:34
#6 block in run (3 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:98
#7 Minitest::Test#capture_exceptions at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:195
#8 block in run (2 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:95
#9 Minitest::Runnable#time_it at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:296
# and 17 frames (use `bt' command for all frames)
(rdbg) f 3 # frame command
=> 35| old_encryptor.decrypt_and_verify(current_encryptor.encrypt_and_sign("test"))
=>#3 block in test_stuff at test.rb:35
(rdbg) info # command
%self = #<BugTest:0x000000011105d7e8 @NAME="test_stuff", @assertions=2, @failures=[]>
old_secret = "RNQ2YepodsSZzyk7cmXLjATDycy1K9WA"
old_encryptor = #<ActiveSupport::MessageEncryptor:0x0000000111d77078 @secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x0000000111d76ad8 @secret="RNQ...>
current_secret = "MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE"
current_encryptor = #<ActiveSupport::MessageEncryptor:0x0000000111d76650 @secret="MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x0000000111d763f8 @secret=...>
@NAME = "test_stuff"
@assertions = 2
@failures = []
(rdbg) c # continue command
DEBUGGER (trace/exception) #th:1 #depth:27 #<ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature> at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178
[19, 28] in ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb
19| include Rotator
20|
21| def decrypt_and_verify(*args, on_rotation: @on_rotation, **options)
22| super
23| rescue MessageEncryptor::InvalidMessage, MessageVerifier::InvalidSignature
=> 24| run_rotations(on_rotation) { |encryptor| encryptor.decrypt_and_verify(*args, **options) } || raise
25| end
26|
27| private
28| def build_rotation(secret = @secret, sign_secret = @sign_secret, options)
=>#0 ActiveSupport::Messages::Rotator::Encryptor#decrypt_and_verify at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:24
#1 ActiveSupport::Messages::Rotator::Encryptor#decrypt_and_verify(args=["RjArNFZBR1VEOGYyQzkwY0ZyRTBTQT09LS1ncVM..., on_rotation=nil, options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:21
# and 24 frames (use `bt' command for all frames)
Stop by #0 BP - Catch "ActiveSupport::MessageVerifier::InvalidSignature"
(rdbg:catch) info
%self = #<ActiveSupport::MessageEncryptor:0x0000000111d77078 @secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x0000000111d76ad8 @secret="RNQ2YepodsS...>
_raised = #<ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature>
args = ["RjArNFZBR1VEOGYyQzkwY0ZyRTBTQT09LS1ncVM2UlNFNW9XYlRqS0pMV0F5ekJBPT0=--c994dbb5b1bc397e7b3c8ba68636633b652864a8"]
on_rotation = nil
options = {}
@aead_mode = false
@cipher = "aes-256-cbc"
@digest = "SHA1"
@on_rotation = nil
@options = {}
@rotations = []
@secret = "RNQ2YepodsSZzyk7cmXLjATDycy1K9WA"
@serializer = Marshal
@sign_secret = nil
@verifier = #<ActiveSupport::MessageVerifier:0x0000000111d76ad8 @secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer, @options={:digest=>"SHA1", :serializer=>ActiveSupport::MessageEncryptor::Null...>
(rdbg) bt # backtrace command
=>#0 ActiveSupport::Messages::Rotator::Encryptor#decrypt_and_verify at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:24
#1 ActiveSupport::Messages::Rotator::Encryptor#decrypt_and_verify(args=["RjArNFZBR1VEOGYyQzkwY0ZyRTBTQT09LS1ncVM..., on_rotation=nil, options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:21
#2 block in test_stuff at test.rb:35
#3 Minitest::Assertions#assert_raises(exp=[ActiveSupport::MessageVerifier::InvalidS...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/assertions.rb:404
#4 BugTest#test_stuff at test.rb:34
#5 block in run (3 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:98
#6 Minitest::Test#capture_exceptions at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:195
#7 block in run (2 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:95
#8 Minitest::Runnable#time_it at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:296
#9 block in run at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:94
#10 #<Class:Minitest::Runnable>#on_signal(name="INFO", action=#<Proc:0x000000011105cb90 /Users/hung-wul...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:391
#11 Minitest::Test#with_info_handler(block=#<Proc:0x000000011105ccd0 /Users/hung-wul...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:243
#12 Minitest::Test#run at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:93
#13 Minitest.run_one_method(klass=BugTest, method_name="test_stuff") at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:1059
#14 #<Class:Minitest::Runnable>#run_one_method(klass=BugTest, method_name="test_stuff", reporter=#<Minitest::CompositeReporter:0x000000011...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:365
#15 block {|method_name="test_stuff"|} in run (2 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:352
#16 [C] Array#each at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:351
#17 block in run at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:351
#18 #<Class:Minitest::Runnable>#on_signal(name="INFO", action=#<Proc:0x000000011105f048 /Users/hung-wul...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:391
#19 #<Class:Minitest::Runnable>#with_info_handler(reporter=#<Minitest::CompositeReporter:0x000000011..., block=#<Proc:0x000000011105f110 /Users/hung-wul...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:378
#20 #<Class:Minitest::Runnable>#run(reporter=#<Minitest::CompositeReporter:0x000000011..., options={:io=>#<IO:<STDOUT>>, :seed=>37767, :args...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:350
#21 block {|suite=BugTest|} in __run at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:182
#22 [C] Array#map at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:182
#23 Minitest.__run(reporter=#<Minitest::CompositeReporter:0x000000011..., options={:io=>#<IO:<STDOUT>>, :seed=>37767, :args...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:182
#24 Minitest.run(args=[]) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:159
#25 block in autorun at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:83
(rdbg) c # continue command
DEBUGGER (trace/exception) #th:1 #depth:26 #<ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature> at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:24
[173, 182] in ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb
173| # secret or was not Base64-encoded.
174| #
175| # other_verifier = ActiveSupport::MessageVerifier.new 'd1ff3r3nt-s3Krit'
176| # other_verifier.verify(signed_message) # => ActiveSupport::MessageVerifier::InvalidSignature
177| def verify(*args, **options)
=> 178| verified(*args, **options) || raise(InvalidSignature)
179| end
180|
181| # Generates a signed message for the provided value.
182| #
=>#0 ActiveSupport::MessageVerifier#verify(args=["UzZwMFNoTlVyZldxaGIzMkEvbi90dz09LS1yMER..., options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178
#1 ActiveSupport::MessageEncryptor#decrypt_and_verify(data="UzZwMFNoTlVyZldxaGIzMkEvbi90dz09LS1yMERk..., purpose=nil) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_encryptor.rb:160
# and 23 frames (use `bt' command for all frames)
Stop by #0 BP - Catch "ActiveSupport::MessageVerifier::InvalidSignature"
(rdbg:catch) info
%self = #<ActiveSupport::MessageVerifier:0x0000000111d763f8 @secret="MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer, @options={:digest=>"SHA1", :serializer=>ActiveSupport::MessageEncryptor::NullSeri...>
_raised = #<ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature>
args = ["UzZwMFNoTlVyZldxaGIzMkEvbi90dz09LS1yMERkMXQ1cjNiNXBXYXV3UWxndnRRPT0=--3c3f86ea0891694b27c9e70bc7401dc40dbeaad2"]
options = {}
@digest = "SHA1"
@digest_length_in_hex = 40
@on_rotation = nil
@options = {:digest=>"SHA1", :serializer=>ActiveSupport::MessageEncryptor::NullSerializer}
@rotations = []
@secret = "MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE"
@serializer = ActiveSupport::MessageEncryptor::NullSerializer
(rdbg) bt # backtrace command
=>#0 ActiveSupport::MessageVerifier#verify(args=["UzZwMFNoTlVyZldxaGIzMkEvbi90dz09LS1yMER..., options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178
#1 ActiveSupport::MessageEncryptor#decrypt_and_verify(data="UzZwMFNoTlVyZldxaGIzMkEvbi90dz09LS1yMERk..., purpose=nil) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_encryptor.rb:160
#2 ActiveSupport::Messages::Rotator::Encryptor#decrypt_and_verify(args=["UzZwMFNoTlVyZldxaGIzMkEvbi90dz09LS1yMER..., on_rotation=nil, options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:22
#3 BugTest#test_stuff at test.rb:39
#4 block in run (3 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:98
#5 Minitest::Test#capture_exceptions at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:195
#6 block in run (2 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:95
#7 Minitest::Runnable#time_it at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:296
#8 block in run at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:94
#9 #<Class:Minitest::Runnable>#on_signal(name="INFO", action=#<Proc:0x000000011105cb90 /Users/hung-wul...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:391
#10 Minitest::Test#with_info_handler(block=#<Proc:0x000000011105ccd0 /Users/hung-wul...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:243
#11 Minitest::Test#run at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:93
#12 Minitest.run_one_method(klass=BugTest, method_name="test_stuff") at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:1059
#13 #<Class:Minitest::Runnable>#run_one_method(klass=BugTest, method_name="test_stuff", reporter=#<Minitest::CompositeReporter:0x000000011...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:365
#14 block {|method_name="test_stuff"|} in run (2 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:352
#15 [C] Array#each at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:351
#16 block in run at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:351
#17 #<Class:Minitest::Runnable>#on_signal(name="INFO", action=#<Proc:0x000000011105f048 /Users/hung-wul...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:391
#18 #<Class:Minitest::Runnable>#with_info_handler(reporter=#<Minitest::CompositeReporter:0x000000011..., block=#<Proc:0x000000011105f110 /Users/hung-wul...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:378
#19 #<Class:Minitest::Runnable>#run(reporter=#<Minitest::CompositeReporter:0x000000011..., options={:io=>#<IO:<STDOUT>>, :seed=>37767, :args...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:350
#20 block {|suite=BugTest|} in __run at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:182
#21 [C] Array#map at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:182
#22 Minitest.__run(reporter=#<Minitest::CompositeReporter:0x000000011..., options={:io=>#<IO:<STDOUT>>, :seed=>37767, :args...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:182
#23 Minitest.run(args=[]) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:159
#24 block in autorun at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:83
(rdbg) c # continue command
DEBUGGER (trace/exception) #th:1 #depth:25 #<ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature> at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178
DEBUGGER (trace/exception) #th:1 #depth:39 #<JSON::ParserError: 859: unexpected token at 'S6p0ShNUrfWqhb32A/n/tw==--r0Dd1t5r3b5pWauwQlgvtQ=='> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:37 #<JSON::ParserError: 859: unexpected token at I" test:ET'> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
[173, 182] in ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb
173| # secret or was not Base64-encoded.
174| #
175| # other_verifier = ActiveSupport::MessageVerifier.new 'd1ff3r3nt-s3Krit'
176| # other_verifier.verify(signed_message) # => ActiveSupport::MessageVerifier::InvalidSignature
177| def verify(*args, **options)
=> 178| verified(*args, **options) || raise(InvalidSignature)
179| end
180|
181| # Generates a signed message for the provided value.
182| #
=>#0 ActiveSupport::MessageVerifier#verify(args=["cDhKYmI2M2pMaFRtUEdHUG9WL3RoUT09LS1NZ0E..., options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178
#1 ActiveSupport::MessageEncryptor#decrypt_and_verify(data="cDhKYmI2M2pMaFRtUEdHUG9WL3RoUT09LS1NZ0E3..., purpose=nil) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_encryptor.rb:160
# and 23 frames (use `bt' command for all frames)
Stop by #0 BP - Catch "ActiveSupport::MessageVerifier::InvalidSignature"
(rdbg:catch) info
%self = #<ActiveSupport::MessageVerifier:0x0000000111d763f8 @secret="MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer, @options={:digest=>"SHA1", :serializer=>ActiveSupport::MessageEncryptor::NullSeri...>
_raised = #<ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature>
args = ["cDhKYmI2M2pMaFRtUEdHUG9WL3RoUT09LS1NZ0E3TitNamFxZ0ZESC95T0pFVWlnPT0=--71a16fa82902807fec3bdaff90b6b1b5e82dd981"]
options = {}
@digest = "SHA1"
@digest_length_in_hex = 40
@on_rotation = nil
@options = {:digest=>"SHA1", :serializer=>ActiveSupport::MessageEncryptor::NullSerializer}
@rotations = []
@secret = "MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE"
@serializer = ActiveSupport::MessageEncryptor::NullSerializer
(rdbg) bt # backtrace command
=>#0 ActiveSupport::MessageVerifier#verify(args=["cDhKYmI2M2pMaFRtUEdHUG9WL3RoUT09LS1NZ0E..., options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178
#1 ActiveSupport::MessageEncryptor#decrypt_and_verify(data="cDhKYmI2M2pMaFRtUEdHUG9WL3RoUT09LS1NZ0E3..., purpose=nil) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_encryptor.rb:160
#2 ActiveSupport::Messages::Rotator::Encryptor#decrypt_and_verify(args=["cDhKYmI2M2pMaFRtUEdHUG9WL3RoUT09LS1NZ0E..., on_rotation=nil, options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:22
#3 BugTest#test_stuff at test.rb:42
#4 block in run (3 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:98
#5 Minitest::Test#capture_exceptions at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:195
#6 block in run (2 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:95
#7 Minitest::Runnable#time_it at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:296
#8 block in run at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:94
#9 #<Class:Minitest::Runnable>#on_signal(name="INFO", action=#<Proc:0x000000011105cb90 /Users/hung-wul...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:391
#10 Minitest::Test#with_info_handler(block=#<Proc:0x000000011105ccd0 /Users/hung-wul...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:243
#11 Minitest::Test#run at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:93
#12 Minitest.run_one_method(klass=BugTest, method_name="test_stuff") at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:1059
#13 #<Class:Minitest::Runnable>#run_one_method(klass=BugTest, method_name="test_stuff", reporter=#<Minitest::CompositeReporter:0x000000011...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:365
#14 block {|method_name="test_stuff"|} in run (2 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:352
#15 [C] Array#each at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:351
#16 block in run at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:351
#17 #<Class:Minitest::Runnable>#on_signal(name="INFO", action=#<Proc:0x000000011105f048 /Users/hung-wul...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:391
#18 #<Class:Minitest::Runnable>#with_info_handler(reporter=#<Minitest::CompositeReporter:0x000000011..., block=#<Proc:0x000000011105f110 /Users/hung-wul...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:378
#19 #<Class:Minitest::Runnable>#run(reporter=#<Minitest::CompositeReporter:0x000000011..., options={:io=>#<IO:<STDOUT>>, :seed=>37767, :args...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:350
#20 block {|suite=BugTest|} in __run at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:182
#21 [C] Array#map at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:182
#22 Minitest.__run(reporter=#<Minitest::CompositeReporter:0x000000011..., options={:io=>#<IO:<STDOUT>>, :seed=>37767, :args...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:182
#23 Minitest.run(args=[]) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:159
#24 block in autorun at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:83
(rdbg) f 3 # frame command
=> 42| assert_nil current_encryptor.decrypt_and_verify(old_encryptor.encrypt_and_sign(nil))
=>#3 BugTest#test_stuff at test.rb:42
(rdbg) info # command
%self = #<BugTest:0x000000011105d7e8 @NAME="test_stuff", @assertions=4, @failures=[]>
old_secret = "RNQ2YepodsSZzyk7cmXLjATDycy1K9WA"
old_encryptor = #<ActiveSupport::MessageEncryptor:0x0000000111d77078 @secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x0000000111d76ad8 @secret="RNQ...>
current_secret = "MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE"
current_encryptor = #<ActiveSupport::MessageEncryptor:0x0000000111d76650 @secret="MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x0000000111d763f8 @secret=...>
@NAME = "test_stuff"
@assertions = 4
@failures = []
(rdbg) up # command
=> 98| self.send self.name
=>#4 block in run (3 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:98
(rdbg) down # command
=> 42| assert_nil current_encryptor.decrypt_and_verify(old_encryptor.encrypt_and_sign(nil))
=>#3 BugTest#test_stuff at test.rb:42
(rdbg) down # command
=> 22| super
=>#2 ActiveSupport::Messages::Rotator::Encryptor#decrypt_and_verify(args=["cDhKYmI2M2pMaFRtUEdHUG9WL3RoUT09LS1NZ0E..., on_rotation=nil, options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:22
(rdbg) info # command
%self = #<ActiveSupport::MessageEncryptor:0x0000000111d76650 @secret="MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x0000000111d763f8 @secret="MUDdXNHTPen...>
args = ["cDhKYmI2M2pMaFRtUEdHUG9WL3RoUT09LS1NZ0E3TitNamFxZ0ZESC95T0pFVWlnPT0=--71a16fa82902807fec3bdaff90b6b1b5e82dd981"]
on_rotation = nil
options = {}
@aead_mode = false
@cipher = "aes-256-cbc"
@digest = "SHA1"
@on_rotation = nil
@options = {}
@rotations = [#<ActiveSupport::MessageEncryptor:0x0000000111d75ea8 @secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x0000000111d75c78 @secret="RNQ2Ye...
@secret = "MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE"
@serializer = Marshal
@sign_secret = nil
@verifier = #<ActiveSupport::MessageVerifier:0x0000000111d763f8 @secret="MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer, @options={:digest=>"SHA1", :serializer=>ActiveSupport::MessageEncryptor::Null...>
(rdbg) c # continue command
DEBUGGER (trace/exception) #th:1 #depth:25 #<ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature> at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178
DEBUGGER (trace/exception) #th:1 #depth:39 #<JSON::ParserError: 859: unexpected token at 'p8Jbb63jLhTmPGGPoV/thQ==--MgA7N+MjaqgFDH/yOJEUig=='> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:37 #<JSON::ParserError: 859: unexpected token at 0'> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
[19, 28] in ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb
19| include Rotator
20|
21| def decrypt_and_verify(*args, on_rotation: @on_rotation, **options)
22| super
23| rescue MessageEncryptor::InvalidMessage, MessageVerifier::InvalidSignature
=> 24| run_rotations(on_rotation) { |encryptor| encryptor.decrypt_and_verify(*args, **options) } || raise
25| end
26|
27| private
28| def build_rotation(secret = @secret, sign_secret = @sign_secret, options)
=>#0 ActiveSupport::Messages::Rotator::Encryptor#decrypt_and_verify at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:24
#1 ActiveSupport::Messages::Rotator::Encryptor#decrypt_and_verify(args=["cDhKYmI2M2pMaFRtUEdHUG9WL3RoUT09LS1NZ0E..., on_rotation=nil, options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:21
# and 22 frames (use `bt' command for all frames)
Stop by #0 BP - Catch "ActiveSupport::MessageVerifier::InvalidSignature"
(rdbg:catch) info
%self = #<ActiveSupport::MessageEncryptor:0x0000000111d76650 @secret="MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x0000000111d763f8 @secret="MUDdXNHTPen...>
_raised = #<ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature>
args = ["cDhKYmI2M2pMaFRtUEdHUG9WL3RoUT09LS1NZ0E3TitNamFxZ0ZESC95T0pFVWlnPT0=--71a16fa82902807fec3bdaff90b6b1b5e82dd981"]
on_rotation = nil
options = {}
@aead_mode = false
@cipher = "aes-256-cbc"
@digest = "SHA1"
@on_rotation = nil
@options = {}
@rotations = [#<ActiveSupport::MessageEncryptor:0x0000000111d75ea8 @secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x0000000111d75c78 @secret="RNQ2Ye...
@secret = "MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE"
@serializer = Marshal
@sign_secret = nil
@verifier = #<ActiveSupport::MessageVerifier:0x0000000111d763f8 @secret="MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer, @options={:digest=>"SHA1", :serializer=>ActiveSupport::MessageEncryptor::Null...>
(rdbg) info # command
%self = #<ActiveSupport::MessageEncryptor:0x0000000111d76650 @secret="MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x0000000111d763f8 @secret="MUDdXNHTPen...>
_raised = #<ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature>
args = ["cDhKYmI2M2pMaFRtUEdHUG9WL3RoUT09LS1NZ0E3TitNamFxZ0ZESC95T0pFVWlnPT0=--71a16fa82902807fec3bdaff90b6b1b5e82dd981"]
on_rotation = nil
options = {}
@aead_mode = false
@cipher = "aes-256-cbc"
@digest = "SHA1"
@on_rotation = nil
@options = {}
@rotations = [#<ActiveSupport::MessageEncryptor:0x0000000111d75ea8 @secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x0000000111d75c78 @secret="RNQ2Ye...
@secret = "MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE"
@serializer = Marshal
@sign_secret = nil
@verifier = #<ActiveSupport::MessageVerifier:0x0000000111d763f8 @secret="MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer, @options={:digest=>"SHA1", :serializer=>ActiveSupport::MessageEncryptor::Null...>
(rdbg) ls self # outline command
ActiveSupport::MessageEncryptor#methods: encrypt_and_sign
ActiveSupport::Messages::Rotator#methods: rotate
ActiveSupport::Messages::Rotator::Encryptor#methods: decrypt_and_verify
instance variables: @aead_mode @cipher @digest @on_rotation @options @rotations @secret @serializer @sign_secret @verifier
class variables: @@use_authenticated_message_encryption
locals: args on_rotation options
(ruby) @rotations
[#<ActiveSupport::MessageEncryptor:0x0000000111d75ea8
@aead_mode=false,
@cipher="aes-256-cbc",
@digest="SHA1",
@on_rotation=nil,
@options={},
@rotations=[],
@secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA",
@serializer=Marshal,
@sign_secret=nil,
@verifier=
#<ActiveSupport::MessageVerifier:0x0000000111d75c78
@digest="SHA1",
@digest_length_in_hex=40,
@on_rotation=nil,
@options={:digest=>"SHA1", :serializer=>ActiveSupport::MessageEncryptor::NullSerializer},
@rotations=[],
@secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA",
@serializer=ActiveSupport::MessageEncryptor::NullSerializer>>]
(rdbg) list # command
19| include Rotator
20|
21| def decrypt_and_verify(*args, on_rotation: @on_rotation, **options)
22| super
23| rescue MessageEncryptor::InvalidMessage, MessageVerifier::InvalidSignature
=> 24| run_rotations(on_rotation) { |encryptor| encryptor.decrypt_and_verify(*args, **options) } || raise
25| end
26|
27| private
28| def build_rotation(secret = @secret, sign_secret = @sign_secret, options)
(rdbg) edit . # command
command: nvim
path: /Users/hung-wulo/src/github.com/ruby/debug
(rdbg) edit # command
command: nvim
path: /Users/hung-wulo/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb
(ruby) @rotations
[#<ActiveSupport::MessageEncryptor:0x0000000111d75ea8
@aead_mode=false,
@cipher="aes-256-cbc",
@digest="SHA1",
@on_rotation=nil,
@options={},
@rotations=[],
@secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA",
@serializer=Marshal,
@sign_secret=nil,
@verifier=
#<ActiveSupport::MessageVerifier:0x0000000111d75c78
@digest="SHA1",
@digest_length_in_hex=40,
@on_rotation=nil,
@options={:digest=>"SHA1", :serializer=>ActiveSupport::MessageEncryptor::NullSerializer},
@rotations=[],
@secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA",
@serializer=ActiveSupport::MessageEncryptor::NullSerializer>>]
(rdbg) edit # command
command: nvim
path: /Users/hung-wulo/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb
(rdbg) bt # backtrace command
=>#0 ActiveSupport::Messages::Rotator::Encryptor#decrypt_and_verify at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:24
#1 ActiveSupport::Messages::Rotator::Encryptor#decrypt_and_verify(args=["cDhKYmI2M2pMaFRtUEdHUG9WL3RoUT09LS1NZ0E..., on_rotation=nil, options={}) at ~/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:21
#2 BugTest#test_stuff at test.rb:42
#3 block in run (3 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:98
#4 Minitest::Test#capture_exceptions at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:195
#5 block in run (2 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:95
#6 Minitest::Runnable#time_it at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:296
#7 block in run at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:94
#8 #<Class:Minitest::Runnable>#on_signal(name="INFO", action=#<Proc:0x000000011105cb90 /Users/hung-wul...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:391
#9 Minitest::Test#with_info_handler(block=#<Proc:0x000000011105ccd0 /Users/hung-wul...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:243
#10 Minitest::Test#run at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest/test.rb:93
#11 Minitest.run_one_method(klass=BugTest, method_name="test_stuff") at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:1059
#12 #<Class:Minitest::Runnable>#run_one_method(klass=BugTest, method_name="test_stuff", reporter=#<Minitest::CompositeReporter:0x000000011...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:365
#13 block {|method_name="test_stuff"|} in run (2 levels) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:352
#14 [C] Array#each at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:351
#15 block in run at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:351
#16 #<Class:Minitest::Runnable>#on_signal(name="INFO", action=#<Proc:0x000000011105f048 /Users/hung-wul...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:391
#17 #<Class:Minitest::Runnable>#with_info_handler(reporter=#<Minitest::CompositeReporter:0x000000011..., block=#<Proc:0x000000011105f110 /Users/hung-wul...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:378
#18 #<Class:Minitest::Runnable>#run(reporter=#<Minitest::CompositeReporter:0x000000011..., options={:io=>#<IO:<STDOUT>>, :seed=>37767, :args...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:350
#19 block {|suite=BugTest|} in __run at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:182
#20 [C] Array#map at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:182
#21 Minitest.__run(reporter=#<Minitest::CompositeReporter:0x000000011..., options={:io=>#<IO:<STDOUT>>, :seed=>37767, :args...) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:182
#22 Minitest.run(args=[]) at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:159
#23 block in autorun at ~/.gem/ruby/3.1.2/gems/minitest-5.16.2/lib/minitest.rb:83
(rdbg) list # command
29| self.class.new(secret, sign_secret, **options)
30| end
31| end
32|
33| module Verifier
34| include Rotator
35|
36| def verified(*args, on_rotation: @on_rotation, **options)
37| super || run_rotations(on_rotation) { |verifier| verifier.verified(*args, **options) }
38| end
(rdbg) list - # command
19| include Rotator
20|
21| def decrypt_and_verify(*args, on_rotation: @on_rotation, **options)
22| super
23| rescue MessageEncryptor::InvalidMessage, MessageVerifier::InvalidSignature
=> 24| run_rotations(on_rotation) { |encryptor| encryptor.decrypt_and_verify(*args, **options) } || raise
25| end
26|
27| private
28| def build_rotation(secret = @secret, sign_secret = @sign_secret, options)
(rdbg) encryptor
DEBUGGER (trace/exception) #th:1 #depth:38 #<NameError: undefined local variable or method `encryptor' for #<ActiveSupport::MessageEncryptor:0x0000000111d76650 @secret="MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x0000000111d763f8 @secret="MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer, @options={:digest=>"SHA1", :serializer=>ActiveSupport::MessageEncryptor::NullSerializer}, @rotations=[], @on_rotation=nil, @digest_length_in_hex=40>, @serializer=Marshal, @options={}, @rotations=[#<ActiveSupport::MessageEncryptor:0x0000000111d75ea8 @secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x0000000111d75c78 @secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer, @options={:digest=>"SHA1", :serializer=>ActiveSupport::MessageEncryptor::NullSerializer}, @rotations=[], @on_rotation=nil, @digest_length_in_hex=40>, @serializer=Marshal, @options={}, @rotations=[], @on_rotation=nil>], @on_rotation=nil>
encryptor
^^^^^^^^^
Did you mean? _encrypt> at (rdbg)//Users/hung-wulo/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:1
eval error: undefined local variable or method `encryptor' for #<ActiveSupport::MessageEncryptor:0x0000000111d76650 @secret="MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x0000000111d763f8 @secret="MUDdXNHTPend6oOxaNyXqZQQHOwxb4JE", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer, @options={:digest=>"SHA1", :serializer=>ActiveSupport::MessageEncryptor::NullSerializer}, @rotations=[], @on_rotation=nil, @digest_length_in_hex=40>, @serializer=Marshal, @options={}, @rotations=[#<ActiveSupport::MessageEncryptor:0x0000000111d75ea8 @secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA", @sign_secret=nil, @cipher="aes-256-cbc", @aead_mode=false, @digest="SHA1", @verifier=#<ActiveSupport::MessageVerifier:0x0000000111d75c78 @secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer, @options={:digest=>"SHA1", :serializer=>ActiveSupport::MessageEncryptor::NullSerializer}, @rotations=[], @on_rotation=nil, @digest_length_in_hex=40>, @serializer=Marshal, @options={}, @rotations=[], @on_rotation=nil>], @on_rotation=nil>
encryptor
^^^^^^^^^
Did you mean? _encrypt
(rdbg)//Users/hung-wulo/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:1:in `rescue in decrypt_and_verify'
nil
(rdbg) list 15 # command
15| @rotations << build_rotation(*secrets, @options.merge(options))
16| end
17|
18| module Encryptor
19| include Rotator
20|
21| def decrypt_and_verify(*args, on_rotation: @on_rotation, **options)
22| super
23| rescue MessageEncryptor::InvalidMessage, MessageVerifier::InvalidSignature
=> 24| run_rotations(on_rotation) { |encryptor| encryptor.decrypt_and_verify(*args, **options) } || raise
(rdbg) list 50 # command
50| on_rotation&.call
51| return message
52| end
53| end
54| end
55| end
56| end
57| end
(rdbg) list 45 # command
45|
46| private
47| def run_rotations(on_rotation)
48| @rotations.find do |rotation|
49| if message = yield(rotation) rescue next
50| on_rotation&.call
51| return message
52| end
53| end
54| end
(ruby) @rotations.first
#<ActiveSupport::MessageEncryptor:0x0000000111d75ea8
@aead_mode=false,
@cipher="aes-256-cbc",
@digest="SHA1",
@on_rotation=nil,
@options={},
@rotations=[],
@secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA",
@serializer=Marshal,
@sign_secret=nil,
@verifier=
#<ActiveSupport::MessageVerifier:0x0000000111d75c78
@digest="SHA1",
@digest_length_in_hex=40,
@on_rotation=nil,
@options={:digest=>"SHA1", :serializer=>ActiveSupport::MessageEncryptor::NullSerializer},
@rotations=[],
@secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA",
@serializer=ActiveSupport::MessageEncryptor::NullSerializer>>
(ruby) @rotations.first.decrypt_and_verify(*args)
DEBUGGER (trace/exception) #th:1 #depth:48 #<JSON::ParserError: 859: unexpected token at 'p8Jbb63jLhTmPGGPoV/thQ==--MgA7N+MjaqgFDH/yOJEUig=='> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:46 #<JSON::ParserError: 859: unexpected token at 0'> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
nil
(rdbg) list # command
55| end
56| end
57| end
(rdbg) list - # command
38| end
39|
40| private
41| def build_rotation(secret = @secret, options)
42| self.class.new(secret, **options)
43| end
44| end
45|
46| private
47| def run_rotations(on_rotation)
(rdbg) list - # command
28| def build_rotation(secret = @secret, sign_secret = @sign_secret, options)
29| self.class.new(secret, sign_secret, **options)
30| end
31| end
32|
33| module Verifier
34| include Rotator
35|
36| def verified(*args, on_rotation: @on_rotation, **options)
37| super || run_rotations(on_rotation) { |verifier| verifier.verified(*args, **options) }
(rdbg) list - # command
18| module Encryptor
19| include Rotator
20|
21| def decrypt_and_verify(*args, on_rotation: @on_rotation, **options)
22| super
23| rescue MessageEncryptor::InvalidMessage, MessageVerifier::InvalidSignature
=> 24| run_rotations(on_rotation) { |encryptor| encryptor.decrypt_and_verify(*args, **options) } || raise
25| end
26|
27| private
(rdbg) q! # quit! command
E
Finished in 1400.692768s, 0.0007 runs/s, 0.0029 assertions/s.
1) Error:
BugTest#test_stuff:
ActiveSupport::MessageVerifier::InvalidSignature: ActiveSupport::MessageVerifier::InvalidSignature
/Users/hung-wulo/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_verifier.rb:178:in `verify'
/Users/hung-wulo/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/message_encryptor.rb:160:in `decrypt_and_verify'
/Users/hung-wulo/.gem/ruby/3.1.2/gems/activesupport-7.0.3/lib/active_support/messages/rotator.rb:22:in `decrypt_and_verify'
test.rb:42:in `test_stuff'
1 runs, 4 assertions, 0 failures, 1 errors, 0 skips
# I checked how run_rotations looks like, and found that it goes through @rotations
(rdbg) list 45 # command
45|
46| private
47| def run_rotations(on_rotation)
48| @rotations.find do |rotation|
49| if message = yield(rotation) rescue next
50| on_rotation&.call
51| return message
52| end
53| end
54| end
# I checked what are the @rotations, and they turned out to be MessageEncryptor objects
(ruby) @rotations.first
#<ActiveSupport::MessageEncryptor:0x0000000111d75ea8
@aead_mode=false,
@cipher="aes-256-cbc",
@digest="SHA1",
@on_rotation=nil,
@options={},
@rotations=[],
@secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA",
@serializer=Marshal,
@sign_secret=nil,
@verifier=
#<ActiveSupport::MessageVerifier:0x0000000111d75c78
@digest="SHA1",
@digest_length_in_hex=40,
@on_rotation=nil,
@options={:digest=>"SHA1", :serializer=>ActiveSupport::MessageEncryptor::NullSerializer},
@rotations=[],
@secret="RNQ2YepodsSZzyk7cmXLjATDycy1K9WA",
@serializer=ActiveSupport::MessageEncryptor::NullSerializer>>
# I knew there's only one rotation in this case, so I checked if it'd decrypt the message
(ruby) @rotations.first.decrypt_and_verify(*args)
# tracer logs, not important
DEBUGGER (trace/exception) #th:1 #depth:48 #<JSON::ParserError: 859: unexpected token at 'p8Jbb63jLhTmPGGPoV/thQ==--MgA7N+MjaqgFDH/yOJEUig=='> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
DEBUGGER (trace/exception) #th:1 #depth:46 #<JSON::ParserError: 859: unexpected token at 0'> at /opt/rubies/3.1.2/lib/ruby/3.1.0/json/common.rb:216
# and then it returned nil, which is the message (if it's not decryptable, it'd raise an error)
nil
# so then I went back to see why the nil value not properly returned
# I "scrolled back" the source code with `list -`
# now I hope https://github.com/ruby/debug/issues/639 could be implemented sooner
(rdbg) list # command
55| end
56| end
57| end
(rdbg) list - # command
38| end
39|
40| private
41| def build_rotation(secret = @secret, options)
42| self.class.new(secret, **options)
43| end
44| end
45|
46| private
47| def run_rotations(on_rotation)
(rdbg) list - # command
28| def build_rotation(secret = @secret, sign_secret = @sign_secret, options)
29| self.class.new(secret, sign_secret, **options)
30| end
31| end
32|
33| module Verifier
34| include Rotator
35|
36| def verified(*args, on_rotation: @on_rotation, **options)
37| super || run_rotations(on_rotation) { |verifier| verifier.verified(*args, **options) }
# after I finally scrolled back, I saw the `||` condition and then it clicked
(rdbg) list - # command
18| module Encryptor
19| include Rotator
20|
21| def decrypt_and_verify(*args, on_rotation: @on_rotation, **options)
22| super
23| rescue MessageEncryptor::InvalidMessage, MessageVerifier::InvalidSignature
=> 24| run_rotations(on_rotation) { |encryptor| encryptor.decrypt_and_verify(*args, **options) } || raise
25| end
26|
27| private
# so I finished the session
(rdbg) q! # quit! command