Mike W
Mike W

Reputation: 401

Security issue with controller

I have my Banks Controller

class Api::V1::BanksController < ApplicationController
  before_action :authenticate_user!
  respond_to :json

  # PUT /api/v1/banks/:id.json
  def update
    @bank = UserBank.find_by!(uuid: params[:id])

    if @bank.update_attributes bank_params
      render json: @bank
    else
      render json: @bank.errors, status: :unprocessable_entity
    end
  end

  private

  def bank_params
     params.require(:bank).permit(:iban, :bic)
  end
end

I'm using devise for the authentication. My problem comes from the fact that any users can update another user's bank object just by getting the access-token from the login response.

Is there a clean/secure/automatic way of preventing a user to interact with somebody else's details ? or should I just make sure that the bank object I'm updating belongs to the logged-in user ?

thanks a lot

Upvotes: 1

Views: 30

Answers (1)

max
max

Reputation: 101821

Your mixing up authentication and authorization.

Authentication is concerned with the identity of the user.

Authorization is a set of rules for who is allowed to do what in your application.

Devise provides authentication, you can either create your own authorization system or use a library (recommended) such as Pundit or CanCanCan.

A hacky home rolled authorization check would look like:

class AuthorizationError < StandardError; end

class ApplicationController
  rescue_from AuthorizationError, with: :deny_access

  def deny_access
    head :unauthorized and return
  end
end

class Api::V1::BanksController < ApplicationController
  before_action :authenticate_user!
  before_action :set_bank!
  before_action :authorize!
  respond_to :json

  # PUT /api/v1/banks/:id.json
  def update
    @bank = UserBank.find_by!(uuid: params[:id])
    respond_with @bank.update(bank_params)
  end

  private
  def set_bank!
    @bank = UserBank.find_by!(uuid: params[:id])
  end

  def authorize!
    # this is the authorization rule.
    unless @bank.user == current_user
      raise AuthorizationError 
    end
  end

  def bank_params
     params.require(:bank).permit(:iban, :bic)
  end
end

Upvotes: 1

Related Questions