Skip to content

Fix: permitted_attributes ignores cannot and default-deny rules#882

Open
tmaier wants to merge 1 commit into
CanCanCommunity:developfrom
tmaier:tmaier-fix-permitted-attributes
Open

Fix: permitted_attributes ignores cannot and default-deny rules#882
tmaier wants to merge 1 commit into
CanCanCommunity:developfrom
tmaier:tmaier-fix-permitted-attributes

Conversation

@tmaier
Copy link
Copy Markdown

@tmaier tmaier commented Aug 2, 2025

This PR fixes a bug in permitted_attributes where it would return a list of attributes for an action, even when that action was explicitly forbidden by a cannot rule or denied by default. The expected behavior in a "default-deny" system is for it to return an empty array.

For example, given the ability:

cannot :update, Project

The call ability.permitted_attributes(:update, Project) would incorrectly return all model attributes, instead of the expected []. This also occurred in default-deny scenarios where no ability was defined at all for a given action.

The Fix

The fix is to add a guard clause at the beginning of the permitted_attributes method. It now uses the core can? method to check if the user is authorized to perform the action before collecting the attributes. If can? returns false, permitted_attributes will now correctly return an empty array.

This ensures that the behavior of permitted_attributes is consistent with the rest of the library's authorization logic.

I considered an alternative which changes the logic of the method completely.
The idea was to collect all forbidden attributes and subtract then the allowed.
And then to return all attributes minus the forbidden attributes.

@tmaier tmaier changed the title Fix permitted_attributes Draft: Fix permitted_attributes Aug 2, 2025
The `permitted_attributes` method was not correctly handling cases where an action was denied by a `cannot` rule or by default.
It would still return a list of attributes from any `can` rules defined for the model, instead of an empty array.

This commit adds a guard clause to check `can?(action, subject)` at the beginning of the `permitted_attributes` method.
If the action is not allowed, it now correctly returns an empty array, respecting the principle of default-deny.

This ensures that attribute sanitization is consistent with the user's defined abilities.
@tmaier tmaier force-pushed the tmaier-fix-permitted-attributes branch from b43059e to 22fe2e2 Compare August 2, 2025 08:48
@tmaier tmaier changed the title Draft: Fix permitted_attributes Fix: permitted_attributes ignores cannot and default-deny rules Aug 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant