Potential security hole authorising modules in CanCan

Nov 7, 2013
ruby, ruby on rails, tech
Just some thoughts on how CanCan didn't work as I expected. Whether design or bug, it's worth checking out how modules are handled.

I got a message from a client this morning telling me that all users could see all reports on our product. Not good. I use CanCan to manage permissions and until now it has served me well. What went wrong? Whether a bug or not, I discovered that a very recent change I made had openned up the hole.

I wanted to have a permission setting that could prevent anyone from seeing any reports as well as more fine grained control over each individual report. My permissions looked a bit like this:

1
2
3
4
5
6
class Ability
  def initialize(user)
    can :read, Reports
    can :read, Reports::ReportA
  end
end

When checking permissions for another report within the module, I didn’t expect this:

1
2
3
4
5
6
7
8
module Reports
  class ReportBController
    def show
      authorize! :read, Reports::ReportB #=> I assumed it would not be authorized but it is
      ...
    end
  end
end

What I didn’t expect is that when you authorise a module, all classes in that namespace are authorised as well.
As I mentioned above, I don’t know if this is by design or not. Some quick googling didn’t help me so I changed my code for a quick solution.

I post this to warn others who may have made the same assumption.
If you’re reading this and know the project better and can point out if it is a bug or feature, please let me know in the comments.

comments powered by Disqus