Rails Security Best Practices - Check For Unauthorized Access

Rails Security Best Practices - Check For Unauthorized Access

How to check if a user is authorized to access a resource in Ruby on Rails

There are several security best practices to protect user data in Ruby on Rails applications. One of which is checking for unauthorized access by a user. This tutorial quickly shows how to check if a user has access to a particular resource before performing an action.

Let's say you have an application with an index of tasks that a user is assigned and is responsible for. The route to a particular resource may be /tasks/4. A user could become curious and change the project id in the url to a different number to see if they can access a different task; one that they may not be assigned and should not have access to.

This type of unauthorized access can be prevented by creating a current_user helper method and setting the task instance variable if the task belongs to the current_user. In this example a user has_many tasks and a task belongs_to a user.

# Application Controller  
class ApplicationController < ActionController::Base 
# other controller actions

  def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
  end

  helper_method :current_user
end
class TasksController < ActionController::Base
  # other controller actions

  def show
    @task = current_user.goals.find_by(id: params[:id])
  end

end

Current User Method

Here we're finding the user based on the user_id in the session; but only if there's a user_id key in the session to begin with. If so, the @current_user instance variable is set to that user. If the tasks does not belong to the user (meaning the user should not have access to the task) @current_user will be set to nil.

The ||= operator is used for memoization in order to realize computational benefits by not performing the same computation if the results have already been computed.

Making current_user a Helper Method

helper_method is used to explicitly share methods passed to it that are defined in the controller and make them available for use in the view. We can designate helper methods to methods that we want to access from both the controller and the view.

In this example, we could use the current_user helper method to display a warning to the user if they do not have access to a particular task.


This is part 1 of the Ruby on Rails - Security Best Practices series.