From: Robert Klemme Date: 2010-10-12T22:06:06+09:00 Subject: Re: Using DRB as a secure interface On Tue, Oct 12, 2010 at 2:34 PM, Anthony Wright wrote: > Is it possible to implement a secure interface exposed to the internet using > DRB? > > I want to pass complex structures through an external API and DRB seems like > an obvious choice, but I'm concerned that DRB will allow code to pass as > well as the data, or methods to be called that I didn't want to be exposed. > > Are my concerns well founded and if so, is there a way to secure the > interface? > > From my simple tests, any modifications to a standard class are not passed, > and non-standard classes are not passed either. Code is never passed. DRb uses Marshal underneath and since that is a data format only without any code you are safe with regard to modifications in client programs. > I tie down the interface class by creating an "EmptyClass" and subclassing > the interface class from that. > > class EmptyClass >        safe_methods = > [:__send__,:__id__,:inspect,:respond_to?,:to_s,:private_methods,:protected_methods,:object_id] > >        (instance_methods - safe_methods).each do |method| >                undef_method method >        end > end You could use BasicObject for that - depending on the Ruby version you are on. irb(main):001:0> Object.ancestors => [Object, Kernel, BasicObject] irb(main):002:0> BasicObject.instance_methods => [:==, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__] > I also carefully check the data in the arguments too. I tried to use $SAFE, > but it got in the way rather than helped. > > Could anybody provide advice on securing DRB and the proper use of $SAFE for > argument checking? You would do it as with any API. DRb really only adds remote method invocation. IMHO your approach to limit the API which is exposed is the first step to get this done. However, you need to do this for *all* classes that you expose via the API which might be quite tedious. Initially I thought you just wanted communication secured (e.g. via SSL). But since you seem to be more concerned with API functionality there is probably only the manual way as described above. However, it is quite unusual to be so restrictive (remember, you can even easily get around "private") so Ruby is probably not too helpful in this area. If you want to allow particular clients only then you might be able to restrict client IP via firewall rules. But that of course depends on your usage scenario. After all the question is: how much security do you want and what are you willing to pay for it (in terms of effort, money or what)? Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/