Restricting access to user submitted code in Rails - ruby-on-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.

Related

Sharing Authentication/Data from Rails to Phoenix?

Background
I have a fairly typical Rails application, which uses Devise for authentication management. While building this app, I realized that realtime chat would be a great feature to have. Ideally, of course, this would make use of Websockets, in order to reduce the polling load on the server (as well as making it marginally easier to implement, as you don't have to manage polling).
I realized quickly that Ruby isn't really a great fit for having a large number of concurrent connections open at one time. Phoenix, however, is written in Elixir, so I can make use of the Erlang VM, which is quite good at long connections. It also seems like it could be greatly beneficial if all the chat data was stored separate from the main application database, which should also reduce load in the future.
The Problem
I want to be able to make this separation completely invisible to the user. They visit www.example.com/chat, and it loads all the relevant data in from chat.example.com and starts up the websockets, without requiring them to login to a separate service. I think using an <iframe> is probably the way to go about doing this.
My problem is sharing authentication and data between the two applications. The Rails app needs to be able to create conversations on the Phoenix app in response to certain events. The Phoenix app needs to know what user is currently authenticated into Rails, as well as general data about the user.
An OAuth flow with the Rails app as the ID provider seemed like a good fit at first, but I can't figure out a way for the Phoenix app to automatically be granted access. I also have some concerns about user records existing inside the Phoenix app—it should be aware of all users on the main application, so you can start a chat with a user even if they haven't ever opened chat.
What would be the best way to go about doing this? My intuition says that this is going to involve window.postMessage and some kind of token system, but I wanted to ask what the generally accepted way of doing this was before I accidentally created an insecure mess.
Sharing the session isn't too hard, assuming you are running at least Rails 4.1 and using JSON serialization (default for apps created with >=4.1). A quick google search finds PlugRailsCookieSessionStore, which accomplishes this.
For more information on what it takes to share a session between Rails and another language, Matt Aimonetti has an excellent blog post with detailed information.
Lastly, if you would prefer to stay entirely in Ruby, it's definitely doable. Ryan Stout discusses scalability around persistent connections in the FAQ for Volt, which uses a persistent connection for every user. The article he links is also a great read. Just mentioning it to help you weigh the trade off of building a separate app in another language.

A ticket System to integrate in Rails

I want to add a Ticket System to the web app I'm developing.
The idea is very simple:
Users can open tickets when they have problems and
the Admin can see the tickets the users have submitted.
I'm looking for a ticket system but I have found only systems that are external to the web. I want to add it IN my wep app.
¿Do you know any ticket system por rails?
Thanks
I think using some external gem like noted above would be either an overkill or a hassle due to mentioned bad documentation.
Judging by your problem description this is quite simple to implement.
Create model for tickets and associations with users (I assume you
already have users model fully set up).
Authorize access to tickets' actions depending on user status (admin
or not)
Create corresponding views
P.S.
You could have a look at Redmine code. It is an open source project management software written in rails. I am sure this could give you a good idea of how to build your own or even borrow bits of code from there (if the app license that you are building fits)
Maybe Simple-Ticket would fit you. Though beware the basic implementation and the fact that there is no documentation provided nor written specs.
Have a look at restrospectiva. It doesn't have any documentation though

Scaling Out: how to handle communication between Ruby on Rails applications?

I am running Ruby on Rails 3 and I have an application that makes use of namespaces in order to handle more "internal concepts". With "internal concepts" I mean that each namespace is used to handle a specific resource of my application. For example a namespace is "users" and it is used to handle user's sessions and authorizations, another is "blogs" and it is used to handle all about posts and comments.
I think this is a "convenient" solution to avoid a lot of problems, but not the best.
At this time my RoR application consists of this file system structure:
# "users" and "blogs" are namespaces
RAILS_ROOT/app/controllers/users
RAILS_ROOT/app/controllers/blogs
RAILS_ROOT/app/models/users
RAILS_ROOT/app/models/blogs
RAILS_ROOT/app/views/users
RAILS_ROOT/app/views/blogs
...
I would like to switch the "users" and "blogs" namespace in two RoR applications using subdomains to have something like this:
http://main.com # This is the main RoR application
http://users.main.com # This is another RoR application used to handle users
http://blogs.main.com # This is another RoR application used to handle blogs
In few words, I think I am trying to Scale Out* my application or maybe to create a Webservice for each RoR application, but my issues are:
1. What problems I may encounter?
I noticed of problems about maintaining sessions (in my case I handle those with cookies) between applications but I think it isn't the only one problem.
2. How to handle communication between the three RoR applications in my case?
I noticed that I can use ActiveResource to share information, but I must pay attention to information such as user authentication.
I have to implement the OpenID/Oauth protocol in order to maintain user authentications?
I think I have to ensure the user authentication information with a HTTPS connection also if the comunication is between subdomains. Is it true?
3. How do I organize my work and resources?
With all that being said, I would like to don't use (absolutely) plugins or gems, but, if I need, I would like to implement my own handler.
At the end I would like to have 3 RoR "easy" and separated applications without use namespaces in each of them and that can communicate between each other:
# "Main" application for http://main.com
ROOT_MAIN/app/controllers/
ROOT_MAIN/app/models/
ROOT_MAIN/app/views/users
...
# "Users" application for http://users.main.com
ROOT_USERS/app/controllers/
ROOT_USERS/app/models/
ROOT_USERS/app/views/users
...
# "Blogs" application for http://blogs.main.com
ROOT_BLOGS/app/controllers/
ROOT_BLOGS/app/models/
ROOT_BLOGS/app/views/users
...
BTW: is a good approach the usage of namespaces that I'm doing?
P.S.: If you need some other information, let me know and I will update the question.
*From The O2 Software Process: "Scale Out" refers to the concept of adding more servers to an existing park, as opposed to "Scale Up" which means to replace existing (slow) servers with newer (and faster) servers.
You problem is lot more simpler than you think. It all depends on how you handle your routes.
Ruby On Rails 3 has better support for Subdomains. So, you need not separate them into three/more RoR apps. You can put all your code in one single RoR app. And redirect user.abc.com to any controller like "users/sessions", redirect blog.abc.com to "blogs/blogs" controller. namespaces are convenient in apps like yours where they make your job really quick to separate out contextually different parts of your app in different folders and route formats.
Try the namespaces to your hearts content, I believe you won't get any errors you are imagining right now. I'd suggest you write code for it and come here if you face problems in it.
Is your app really so big that you need to use multiple apps to handle the different concerns? It could be that your post just lacks enough detail to convey the real magnitude of what you are doing but it seems like you are trying to modularize a small enough app that it would be fine without "scaling out" as you say. Or maybe I am just missing something?
I think that is going to be a tricky problem but there may be some way to store session data in the database and either share it the way you handle #2 or you'll have to roll a custom solution for that. I think the biggest problem will be sharing resources across your app, and also if you are breaking user management out into its own app you'll need to implement your own OpenID/Oauth. This post describes this with Devise/OAuth.
You can use activeresource to connect to each app's respective rest api. This post describes one guy's solutions to sharing data across rails apps.
This question is somewhat vague. You described using multiple apps to separate your concerns (blogging vs user management), so I imagine you'll have your resources at the root of each application without any namespacing, as you've done already in your existing application.
Now for a more general response to your entire question, recently I read a blog post regarding Data, Context and Interaction (wikipedia article) on Rails, and I think this might be a better solution for what you are trying to accomplish if you feel like your app is getting out of control.
Sorry for answering this late.
Actually if you want to scale your rails application you need not create different apps for each unit(I mean as you are trying to separate out users and blogs here), you are jumping a step ahead in the process of scaling your app you should first put all individual units as mountable engines and require them as gem in your core application and mount them in your core app routes.As in your case blogs can be moved to a separate mountable engine.If in future you require to scale more then you can move futher to use engines as separate application.Here's a link to a video that may give you idea what I am trying to explain here https://www.youtube.com/watch?v=pm94BsoMGik

Using Devise to implement a front-door on a website, does Rails allow concurrent sessions?

First, my obligatory "I'm new to rails" statement: I'm new to rails.
Sorry for the following long-winded expository stuff, but I want to make sure I'm asking my question clearly. I'm building a sample manager for a small analytical lab. So far I have built the core user stuff using devise to manage sessions (Basically so I can use all of Devise's nice helper methods throughout my app). The users don't need to be securely separated, so there is no sign in form, it just automatically signs them in for whatever action the user wishes to do.
I would like to put a front door on the website for macro-security that signs in to either the user version of the site (described above) or the admin version. I understand how to implement this using Devise, however, I am unsure as to whether Rails allows this sort of double-session where there's a macro-security session on constantly while a bunch of internal sessions are created and destroyed. Again, sorry for the long-windedness and thanks for your time and help!
Decided to just give it a shot and it turns out it worked. I have to test to see if there are any kinks in the functionality, but as it stands it works well as a front-door while allowing the internal transient sessions.

How to safely let users submit custom themes/plugins for a Rails app

In my rails app I'd like to let users submit custom "themes" to display data in various ways.
I think they can get the data in the view using API calls and I can create an authentication mechanism for this. Also an authenticated API to save data. So this is probably safe.
But i'm struggling with the best way to let users upload/submit their own code for the theme.
I want this to work sort of like Wordpress themes/plugins where people can upload the thing. But there are some security risks. For example, if I take the uploaded "theme" a user submits and put it in it's own directory somewhere inside the rails app, what are the risks of this?
If the user inserts any rails executable code in their theme, even though it's the view they have full access at that point to all the models, everyone's data, etc. Even from other users. So that is not good.
I need some way to let the uploaded themes exist in a sandbox of the rails app, but I haven't seen a good way to do this. Any ideas?
You could try Liquid (http://www.liquidmarkup.org/), which was developed to allow users to create their own themes for Shopify. Liquid themes aren’t real Ruby code, so you shouldn’t have to worry about users trying to access things they shouldn’t.
Another option is Ruby’s concept of “tainted” objects, which could be used to implement secure themes/plugins while still allowing users to write actual Ruby code. You can read more about it here. I can’t vouch for how secure it is as I’ve never used it.
It looks like this might have potential:
http://flouri.sh/2007/10/27/safely-exposing-your-app-to-a-ruby-sandbox
I'm also thinking about letting users submit their own sinatra apps and then running them from within rails. It looks like with Rack routing this is possible. I haven't been able to find any data on how/if the sinatra app is sandboxed from the rails app though. If anyone has info please let me know!

Resources