Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Allow per-class whitelisting of methods safe to expose through DRb #50

Closed
wants to merge 3 commits into from

3 participants

@mohamedhafez

Allows the optional declaration of a whitelist of methods to expose through DRb for any class DRb will be sharing an instance of. (The current behavior of exposing all public methods of a class can leave a pretty scary security hole in some applications)

If drb_safe_methods is used in a class's definition, then any attempt to call a non-whitelisted method on that class through DRb will fail. There is no change to DRb's normal behavior if drb_safe_methods has not been called in a class's definition.

mohamedhafez added some commits
@mohamedhafez mohamedhafez Allows the optional declaration of a whitelist of methods to expose t…
…hrough DRb for any class DRb will be sharing an instance of. (The current behavior of exposing all public methods of a class can leave a pretty scary security hole in some applications)


If drb_safe_methods is used in a class's definition, then any attempt to call a non-whitelisted method on that class through DRb will fail. There is no change to DRb's normal behavior if drb_safe_methods has not been called in a class's definition.
0be2422
@mohamedhafez mohamedhafez whoops, I was checking @front each time for the drb_safe_methods_list…
…, in order to deal correctly for DRbUndumped objects i needed to pass it the actual obj from check_insecure_method and check that instead
704c7a6
@shyouhei
Owner

Hi. I forwarded this issue to our ITS:

http://redmine.ruby-lang.org/issues/5434

Please follow the discussion there. I can do the pull once you get consensus.

@mohamedhafez mohamedhafez I was accidentally classifying private methods, protected methods,and…
… unimplemented methods as insecure methods. this commit fixes that
96665e3
@zzak
Collaborator

Closing this as there is already an open ticket in redmine

@zzak zzak closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 27, 2011
  1. @mohamedhafez

    Allows the optional declaration of a whitelist of methods to expose t…

    mohamedhafez authored
    …hrough DRb for any class DRb will be sharing an instance of. (The current behavior of exposing all public methods of a class can leave a pretty scary security hole in some applications)
    
    
    If drb_safe_methods is used in a class's definition, then any attempt to call a non-whitelisted method on that class through DRb will fail. There is no change to DRb's normal behavior if drb_safe_methods has not been called in a class's definition.
Commits on Sep 29, 2011
  1. @mohamedhafez

    whoops, I was checking @front each time for the drb_safe_methods_list…

    mohamedhafez authored
    …, in order to deal correctly for DRbUndumped objects i needed to pass it the actual obj from check_insecure_method and check that instead
Commits on Oct 19, 2011
  1. @mohamedhafez

    I was accidentally classifying private methods, protected methods,and…

    mohamedhafez authored
    … unimplemented methods as insecure methods. this commit fixes that
This page is out of date. Refresh to see the latest.
Showing with 34 additions and 3 deletions.
  1. +34 −3 lib/drb/drb.rb
View
37 lib/drb/drb.rb
@@ -1437,10 +1437,16 @@ def run
]
# Has a method been included in the list of insecure methods?
- def insecure_method?(msg_id)
- INSECURE_METHOD.include?(msg_id)
+ # Or, if a list of drb-safe methods has been defined for the
+ # front object, is this method not included in that list?
+ def insecure_method?(obj, msg_id)
+ INSECURE_METHOD.include?(msg_id) ||
+ (obj.public_methods.include?(:drb_safe_methods_list) &&
+ obj.public_methods.include?(msg_id) &&
+ !obj.drb_safe_methods_list.include?(msg_id))
end
+
# Coerce an object to a string, providing our own representation if
# to_s is not defined for the object.
def any_to_s(obj)
@@ -1460,7 +1466,7 @@ def any_to_s(obj)
def check_insecure_method(obj, msg_id)
return true if Proc === obj && msg_id == :__drb_yield
raise(ArgumentError, "#{any_to_s(msg_id)} is not a symbol") unless Symbol == msg_id.class
- raise(SecurityError, "insecure method `#{msg_id}'") if insecure_method?(msg_id)
+ raise(SecurityError, "insecure method `#{msg_id}'") if insecure_method?(obj, msg_id)
if obj.private_methods.include?(msg_id)
desc = any_to_s(obj)
@@ -1768,6 +1774,31 @@ def fetch_server(uri)
module_function :fetch_server
end
+
+# Declare a list of methods to expose to DRb
+#
+# Allows the optional declaration of a whitelist of methods to expose
+# through DRb for any class DRb will be sharing an instance of. If
+# drb_safe_methods is used, then any attempt to call a non-whitelisted
+# method on that class through DRb will fail.
+#
+# EXAMPLE USAGE:
+# def MyClass
+# drb_safe_methods :method1, :method2
+# end
+#
+# NOTE: if you are using irb as the client and :to_s isn't in the list,
+# you will get a DRb::DRbConnError when you create the DRbObject, but only
+# because irb calls to_s to display the result; the DRbObject is still
+# usable.
+class Class
+ def drb_safe_methods(*symbols)
+ define_method(:drb_safe_methods_list) do
+ symbols
+ end
+ end
+end
+
# :stopdoc:
DRbObject = DRb::DRbObject
DRbUndumped = DRb::DRbUndumped
Something went wrong with that request. Please try again.