Potential security hole authorising modules in CanCan
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.