From: Garthy D Date: 2011-12-18T17:37:49+09:00 Subject: Re: Ruby, SAFE, method interception, and plugins A quick addendum: I forgot to mention that I'm quite comfortable using Ruby, embedded Ruby, and the like- I just haven't worked on anything resembling this problem with Ruby before. On 18/12/11 18:46, Garthy D wrote: > > Hi all, > > I am working on an embedded Ruby application that may support > user-written Ruby plugins in the future, and I am trying to get a rough > idea as to what is and isn't possible, as it will affect the design I go > with. Basically, if you've worked on such a thing before, please share > your experiences. :) > > The ideal in my case is that the app will load in user-written Ruby code > as a plugin, and the plugin author can interact with the rest of the > code via a predefined and restricted set of objects and methods, but > cannot mess with things outside of its environment, and especially not > start exploring outside that environment in any way. I want to be able > to completely lock the user out of using certain objects or classes. > > Having not done anything like this in Ruby before, I'm trying to get a > feel as to what might be possible and practical. > > For example, many of the criteria in a $SAFE level of 4 seem appropriate > to me- although what I'm really after is a way to lock things up, call > some user code, and then revert back to a normal $SAFE level. It looks > like the only way this could really be done though is to launch the > plugin in its own (Ruby) thread and handle any synchronisation issues > arising from it myself. Is this right? > > Being able to set up my own access control by intercepting every method > call made by the plugin would also be useful. I could then, for example, > have a set of testing criteria that I could use on each method call to > determine if it should be allowed (for example, class whitelists). I > wonder if I could set up a series of proxy objects for objects that I'd > like to wrap, but I wouldn't want a plugin author to use those proxy > classes to get at the original objects, and mess with them directly. The > interface could be as thin as two objects- an application object that > you send messages to, and a plugin base object that the plugin uses to > receive messages from the application. In this case I'd like the user to > be able to create their own classes, manipulate strings and arrays (for > example), but not interact with any of the remaining Ruby code at all, > and certainly not examine it in any way. > > As some app users might run plugins other app users have written, being > able to limit the damage they can cause is also important. I'm not > fussed if certain operations could cause a denial of service (eg. just > run "while true; end"), as the environment would be such that the > affected user could just kill the process and disable the plugin- it's > not a web server. I *would* be fussed though if the plugin was able to > read and write files to the system directly, or cause lasting damage > outside of the application itself. > > As you can tell, my thoughts on the subject are still somewhat > disorganised. I'm trying to determine roughly which parts of this > infrastructure would be easy, difficult, or impossible to implement. I > would greatly benefit from the thoughts and experiences of people who > have been down this road before. If you can find the time, please share > your experiences, and let me know what worked, and what did not. > > Thanks in advance, apologies for the long, rambling question. :) > > Garth >