Is it possible to restrict the functionality of JRuby? - ruby

Suppose that I have a Java program that uses JRuby to allow the user to use Ruby scripting to control the behaviour of some funny character in a window.
Users can share their Ruby code with the community, so others can execute the snippets on their own copy of the program and see the funny character do stuff.
I have a security concern with this, though, as users may contribute malicious Ruby code to the community.
The obvious precaution is that users shouldn't run the snippets of untrusted users. However, due to the nature of the community, the point is to check out the creations of strangers.
So, it has occurred to me that maybe I can restrict the capabilities of JRuby.
There may be other things, but some of the restrictions off of my head would be:
Do not allow any sort of networking.
No access to the filesystem.
Do not permit system DOS calls.
Can't require/import ruby code/gems/etc.
Can't create new processes etc.
Is there a reasonable way to restrict JRuby functionality?
I have thought of, perhaps, redefining several constants that are required for that sort of operations. For instance,
File = nil
But I am unsure of what constants to nullify exactly, and whether this is effective at all.

since your requirements are concrete you would likely need to implement those restrictions yourself ... some pointers :
rubygems can be disable within JRuby - assuming it's fine for you to boot that way, otherwise chaing load/require is a good option
same for system and similar calls that create a new process
instead of doing File = nil early on you might end up needing to review File/IO methods one by one
undefine Java constant and java methods to disallow smart cheating with Java APIs

Related

Ruby Mock a File and Check Contents

I am writing a gem which adds dependencies to a gemfile from the command line. Given the gem name, it grabs the latest version from rubygems and adds it to the user's gemfile.
I practice test driven development using rspec. I'm wondering how do I mock the existence of a file and check it's contents?
Is there any pattern for doing this sort of thing? Tips, links or examples will help. I'm not set on a specific way of testing this. If mocking isn't the way to go, please let me know. Thanks!
If you want to mock a file object that only needs to be written and read from (no filesystem operations), try Ruby's builtin StringIO. Just require 'stringio', create a 'file' with any contents by using StringIO.new("Some contents"), and check its contents by using the string method on the StringIO object.
Unit Tests vs. Integration Tests
You didn't post any code, so I'm going to have to make some assumptions. In general, exercising behavior from Ruby's core or standard libraries is a waste of time. In addition, your tests should exercise methods that define class behavior, not necessarily every single method in a class.
When you cross the boundary to testing I/O, you're often doing integration tests. Sometimes integration tests are necessary, but they should make a very small subset when compared to unit tests.
With all that said, while integration tests that involve filesystem, database, or network I/O are often slower than unit tests, whether or not they are slow enough to warrant stubbing, mocking, or test-specific work-arounds will be specific to your code base.
Options for Testing
If you really need to do this, you have a lot of options. Some of these options include:
Using a RAM disk for your filesystem I/O.
Stubbing calls to IO, File, or FileUtils.
Avoiding the issue by using a file fixture.
Avoiding the issue by using a StringIO fixture.
Re-writing your class under test to accept String and/or StringIO in addition to File objects.
Using a gem like FakeFS to handle the stubbing/mocking for you.
This isn't meant to be an canonically exhaustive list. There are doubtless other options, but one or more of the above should handle any common use case.

Best practice for adding other language files in ruby project

I have a ruby project written purely in ruby. Now I want to include a java archive (jar) file which has some functionality my users want. It is good to just place the file in one of the directories and bundle as a gem? Are there any security issues related to this? Any advice would be greatly appreciated.
The answer is that it depends on the use case.
If this is a gem that users will be using purely for their own purposes, and it's not broadcasting over a network, then security issues are fairly minimal - they would relate more to system security.
If part of your program involves binding to a port and accepting TCP/UDP connections then you've got to really start thinking about network security. Another possible problem is if you're giving file system access to non-privileged users (e.g. if this is a rails gem, and the JAR gives functionality to manipulate the file system and for some reason you're passing this on to the site users - bit of a stupid example but I hope you see what I'm getting at).
However, as for running a java JAR file, there's nothing innately insecure about that unless there are known security flaws with that particular JAR.
In the end, it's up to the end-user of the gem. Make it clear what the gem does and they can make the decision about whether they want to use it.

Preventing filesystem access and other destructive actions

I would like to create a small Rails application that would allow users to give a few snippets of code to benchmark in multiple implementations and versions of Ruby. I am capable of creating the application, I am just afraid of users mucking around in the filesystem or doing other destructive actions. Is there any way to prevent this?
There is $SAFE:
The variable $SAFE determines Ruby's level of paranoia.
The various "safety levels" are noted at the link, there's also some examples (which still work) of using a thread, $SAFE, and load to wrap untrusted code. $SAFE on ruby might be worth a look as well.

Is communication between two ruby processes possible/easy?

If I have a ruby script Daemon that, as it's name implies, runs as a daemon, monitoring parts of the system and able to perform commands which require authentication, for example changing permissions, is there an easy way to have a second ruby script, say client, communicate to that script and send it commands / ask for information? I'm looking for a built in ruby way of doing this, I'd prefer to avoid building my own server protocol here.
Ruby provides many mechanisms for this including your standards such as: sockets, pipes, shared memory. But ruby also has a higher level library specifically for IPC which you can checkout Here, Drb. I haven't had a chance to play around with it too much but it looks really cool.
You may want to look into http://rubyeventmachine.com/

Ruby: intelligent patch/update

After being blown away by the greatness of irb and rails console, I am loving the dynamical parts of the language more and more. Now, I wonder if it would be possible for a Ruby application to update itself on-the-fly (if the write permission allows it). Can a Ruby application fetch an update and refresh itself? I have seen this functionality a lot in Apple applications and I know updates and fixes are something you must anticipate for when deploying an application.
Thank you for your feedback, comments and answers!
Sure. You can load a file that re-opens an existing class and alters behavior. There are a few ways to get the new code, too. Read it off disk, or have a socket that accepts connections and then eval the strings passed in. Or use HTTP: http://www.neurogami.com/articles/The_year_of_living_dangerously/
BTW, there's some risk involved with doing thngs this way. :)

Resources