Skip to content

Misleading Access Check from SecurityChecker::isGranted with unanimous Access Decision Strategy #32594

@dsentker

Description

@dsentker

Symfony version(s) affected: 4.3, probably older versions are affected as well

Description
It is not uncommon to check the access rights via is_granted in twig templates. Internally, SecurityChecker->isGranted($role, $object) is called for this. The documentation states that

If several roles are passed in an array, true is returned if the user has at least one of them.

However, this is not correct in all cases. Either there is an inaccuracy in the documentation, or the behavior of SecurityChecker->isGranted($role, $object) is unintentionally dependent on the Access Decision Strategy. If the access decision strategy is set to unanimous , then is_granted will only return true if ALL of the given roles are assigned to the user.

How to reproduce
For example, use this security configuration

[...]
access_decision_manager:
    strategy:             unanimous
    allow_if_all_abstain: false

If a user as the role "ROLE_A" (without ROLE_B)

{% if is_granted(['ROLE_A', 'ROLE_B']) %}
    <p>Current user has ROLE_A or ROLE_B</p>
{% endif %}

then the paragraph is not shown.

Possible Solution
The simplest solution is to point out in the documentation that in a given configuration setting, multiple roles in is_granted are checked with AND (instead of OR).

Nevertheless, it would make sense to also perform an OR query on the unanimous strategy (to check whether the user has one of these roles)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions