Restrictions on user-submitted code - ruby-on-rails

I have a Ruby on Rails application, and one of its functions is to present JSON data to the user in table form. Before this step, I intend to add a way for users to tweak the JSON data by means of uploading their own Ruby code files that handle this.
This has its dangers. I definitely don't want any form of access (reading or writing) to the databases, nor do I want it to be able to call anything in another file. How can I limit the file in this way?
Essentially all I need is for the main code to call the function in the user-submitted file with the JSON as the parameter, and returning JSON back. All logic during this manipulation of the JSON must happen in and only in the user file.
I've looked around for ways to do this with no luck. I've seen this question:
Restricting access to user submitted code in Rails
The issue here is that I'd prefer an approach that doesn't require a gem. Also sandboxing seems rather complicated for the approach I want, which is a blanket restriction, and not specific things.
I intend to raise the $SAFE level to 4 before calling the user-supplied code/method. That doesn't seem to prevent calling other methods in the application though.

Related

Restricting access to user submitted code in Rails

I'm working on a rails application that takes ruby code as input and executes it. Since the code submitted comes from an untrusted domain, I want to restrict access to certain methods and modules. For example, I don't want users to access File.read or open().
Also, is it possible to restrict access to only a few modules? Only modules from a whitelist can be required from user submitted code.
I can probably do a validation on the user code, but I wanted to check if ruby language or any modules already have this capability.
Codeschool.com has interactive tutorials. I am wondering if they restrict access to user code or do any validation at all.
Ruby has a built in feature for that, $SAFE
Some basic intro you can find here http://edwinmeyer.com/Release_Integrated_RHG_09_10_2008/chapter07.html
and then you can easily google more (I can recommend only books)
Also take a look in here
http://www.ruby-doc.org/docs/ProgrammingRuby/html/taint.html
From what I remember the solution here is to load your app, then raise $SAFE level to 4 in a thread, execute code there (this can't be lowered later so you first need to allow Rails to load in level 0)
I've always used shikashi with satisfaction for this kind of tasks.

Correct rails place for no-db data fetching code

I'm looking for the "rails" design pattern for code that fetches data from other websites.
I have a rails controller in my app that fetches data not from the database, but from external API's or scraped from the web.
Where's the "rails" place to put this code.
For quick implementation, I just stuck it in a model, but the model doesn't interact with the database - or support standard model functionality - so that feels wrong, but my understanding of rails and ruby isn't yet solid enough to know where it should go.
The way the code works roughly is
controller calls model.fetchData args
the model uses HTTParty or similar to make the call
processes data
passes it back to the controller
Any advice?
Broadly-speaking I think there are two possible ways to do this:
Create a plain ruby class to contain the methods for making requests to the API(s) and processing responses from it(them). You can include the HTTParty module in this class with include HTTParty. The usual place to put this code is in lib/ (make sure that wherever you put it, the path is in autoload_paths).
If you're doing anything really complex, or the API itself is complex, you might want to consider creating a separate gem to handle interaction with the API(s). The term for this type of gem is an "API wrapper" -- if you look around, you'll see there are lots of them out there for popular services (Twitter, LinkedIn, Flickr, etc.)
Notice I haven't mentioned activerecord. If you're not going to be saving anything to the DB, I don't see any need to even create any activerecord models. You can get by with just controllers and views, and then (if needed) pick and choose components from activemodel (validations, internationalization, etc.) to make your ruby API wrapper class feel more like a Rails model. For example, one thing that I've done in an app I'm working on is to apply validations to query strings before actually making requests to an external API, which is a bit like running validations on database queries before querying a DB. See this article by Yehuda Katz for more on how to make plain ruby objects feel like activerecord models.
Hope that helps. I answered another question very similar to this one just yesterday, you might want to have a look at that answer as well: Using rails to consume web services/apis

Where to put completely miscellaneous code in a Rails app

I have a rails app the works with multiple 3rd party APIs. Some of these APIs are rate limited and many have methods that can take hours to complete and you have to continually check to see if your request is ready. As such, I have built a queueing system to manage all the baggage.
Each request that goes into this queue has a JSON string that details which 3rd party API the request pertains to, which method, what arguments and a callback to handle the response. I'm going to need a good many callback methods and they handle wildly different tasks. Some update the service status of the 3rd party, some update customer information, some create another queued request to download a large CSV or parse a CSV, etc.
I'm not sure where to put all these unrelated callback methods. They are so varied and meddle with so many different models that I'm not sure it's right to put them under the QueuedRequest model (although that seems the easiest especially regarding testing). I'd like to consolidate them in a single place (again to make testing easier) so trying to shoehorn them into their related models (though often they may not be related to a model at all) isn't going to work.
A utility class of sorts seems to be the best place but where would I put that file?
Details:
Rails 3.2.6
Update: To elaborate on the answer below, what I ended up doing was putting a module of utility methods in /lib/api. I added /lib/api to my autoload_paths in /config/application.rb and, unmentioned, I created an initializer to load the module into my app for me.
/lib/api/callbacks.rb
module Callbacks
extend self
def some_method
# magic
end
end
/config/application.rb
config.autoload_paths += %W(#{config.root}/lib/api)
/config/initializers/application.rb
require 'callbacks'
Under the lib directory, and don't forget to add it to your autoload paths (or eagerload paths if your app is threadsafe!). Make a folder called api and then stick that stuff in a namespace
For example, lib/api/stack_overflow.rb
module API
class StackOverflow
# schtuff
end
end
You could always just throw it into the lib folder.
I am working on an application which queries an external API and presents the data to the user without actually saving it to the DB. There are various elements involved in this process (passing the API key and user ID to the API, validating the query parameters in the request, parsing the response, etc.) which don't have a lot to do with the actual rails application (which will be mainly focused on presenting this data to the user), so I split off all the API stuff into its own directory under lib.
By doing it this way I can test it separately from the main application, which makes for a clean separation of concerns. Also, since my classes for the library are not based on activemodel, the library can be spun off into its own gem and potentially used in other non-rails projects. I have considered, for example, switching rails for sinatra, which is easy to do given the current setup.

Helpers in rails

I'm just starting out in Rails and there's a lot I still need to learn so I'm likely to be on Stackoverflow more often than normal asking beginner Rails / Ruby questions.
I'm just trying to figure out how Helpers work in Rails. From what I've seen so far, Helpers are intended to be used with Views and not so much with your Controllers.
However I would like to make a simple function that will validate the user input given in params (check if certain params are defined and optionally check if their value is valid).
Can anyone explain to me what would be the best way of implementing this? (Keeping in mind that I will want to use this in many different controllers so it should be globally available.)
I also noticed that by default Rails does not generate a lib folder in the main application folder. Are developers to place their libs outside the app folder in the main folder, or does Rails use libraries differently?
With regards to your validation issue, it depends on what you are validating.
If the data makes up objects from your problem domain, also known as models, then you should use the built in validators from ActiveModel. This is probably what you should do, but its hard to say without knowing the exact problem. See the Rails Guides on Validations. You can tell if this is the case by asking yourself if the data that needs validation will be stored after you get it. If so, its most definitely a model. An example of this kind of data would be the title and text fields of a blog post being sent to Rails from a browser form.
If the data is something tertiary to your models, or specific to presentation, then you should be fine using helpers. You noticed that helpers are used mostly in the views, and although this is true, theres nothing stopping you from using them in the controllers, you just have to declare that you will use them using the ActiveController#helper method. Inside the ApplicationController class, a lot of devs will put helper :all to just include all the helpers in all the controllers. Once the code has been required once, it doesn't really incur that big a performance hit.
Do note that almost all incoming data can be modeled using a model. A big school of thought in the Rails world subscribes to the Fat Model idea. People say that putting as much code as possible in the model and as little in the controller as possible separates concerns properly and leads to more maintainable code. This suggests that even if you don't think the incoming data is modelable (in the sense that you can create a model to represent it), you should try to make it a model and encapsulate the logic around validating it. However, you may find that making a helper function is faster, and either will work.
Your notion of validating user input is a good one. I get the feeling that as you are new to Rails you are used to doing these things yourself, but that doesn't quite apply here. In the Rails world, a lot of the common stuff like validations is handled by the framework. You don't have to check for presence in the params array, instead you call validates_presence_of on the model and let Rails spit the error out to the user. It makes things easier in the long run if you let the framework do what it is designed to.
With regards to your question about the lib folder, it doesn't really matter. You can put miscellaneous support files and libraries in the lib folder in the root directory and they will be available for use in your application (the files in the app folder). You can also choose to abstract your code into a plugin or a gem and include it that way, which a lot of people opt to do. My suggestion for this would be to read up on the notion of gems and plugins before diving in.
Want you want is probably a custom validator (in Rails3):
http://railscasts.com/episodes/211-validations-in-rails-3
You can either add libs in a lib folder you create, or add them to config/initializers in a file you add. Files in the initializers directory are automatically loaded by Rails.

Calling application from rails

I have an existing website/application that uses COBOL-CGI where the COBOL app creates the html pages by filling in data using placeholders.
I now want to create a rails site that in addition to using its own db, should also call the external application to retrieve various information.
Can this application still be called using cgi?
Is there a better way to call 3rd party applications from rails? ActiveX?
You probably want to do it a little differently. You can have the Rails application call the COBOL CGI, but the current one is creating HTML, which you'd need to scrape for the data.
Probably you'd be best off to modify the COBOL to generate some simpler representation, down to and including just a CSV file, although YAML or JSON might be a little easier to use. Then you can invoke the COBOL application, and capture its output for use by the rails application.

Resources