-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Security] RoleSecurityIdentity checks for instances of RoleInterface to allow custom Role implementation #8313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@schmittjoh can you verify this change? |
This come back like boomerang =) i.e. #5909 |
@stloyd but the problem is that ALL others are closed as "duplicate" of another one, and none is actually opened to be considered. So closing this one means we'll be back to no PR opened related to this. |
@@ -50,6 +51,32 @@ public function getCompareData() | |||
array(new RoleSecurityIdentity('ROLE_FOO'), new RoleSecurityIdentity(new Role('ROLE_FOO')), true), | |||
array(new RoleSecurityIdentity('ROLE_USER'), new RoleSecurityIdentity('ROLE_FOO'), false), | |||
array(new RoleSecurityIdentity('ROLE_FOO'), new UserSecurityIdentity('ROLE_FOO', 'Foo'), false), | |||
array(new RoleSecurityIdentity('ROLE_FOO'), new UserSecurityIdentity('ROLE_FOO', 'Foo'), false), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this duplicate line intentional?
According to af70ac8 @schmittjoh considered this change as a security vulnerability. So, I can't see how @schmittjoh understands that it is a security vulnerability, but I'd love if he can provide a clear explanation why is it considered like that. Otherwise, it seems that all those 10 PRs that were already highlighted before are valid. Finally, if it is indeed a security vulnerability, there's no need to provide a contract for extensibility (interface) if implementors are unable to correctly consume the API. It just seems non-sense. |
Additionally, if there is indeed a security vulnerability here, it would be great to get a test case to cover that situation so that we can ensure that other changes don't trigger similar flaws. |
I remember talking with Fabien about this. I think a better approach is to override the SecurityIdentityRetrievalStrategy if you need this. Regarding the security vulnerability, this does not necessarily introduce something, but depending on the assumptions that you make in your system, especially if you use different role classes, it could. That's why I'd prefer to not make this change. |
@schmittjoh Please, could you elaborate more about the security vulnerability? We have 12 tickets about the same subject, one is 2 years old and unfortunately I couldn't find the vulnerability explanation. A viable option may be to override the If the decision is to close and do not accept this pull request we must remove the
With the actual constructor we know that this |
The latter is also something that I suggested, and removing the entire On Thu, Jun 20, 2013 at 3:19 PM, Danilo Cabello notifications@github.comwrote:
|
@schmittjoh That doesn't mean anything to me. I could extend Role class then and do whatever I want.
That's a more lengthy explanation why I think this concern is invalid and the patch should be merged. |
@fabpot can you provide some feedback on this? |
Any news on this one? |
nanananananananana batman! |
👍 for merging... A developer can always introduce a security vulnerability, by any means. I recommend |
@aderuwe I tried once |
@guilhermeblanco I don't think All things considered, I think that (as is the case with the |
it needs some rebasing |
@cordoval What do you mean? Are you trying to use our fork (instaclick/symfony) and is it missing the latest changes from symfony? |
@cabello currently, it has conflicts when we try to merge this. That means that this branch is not up-to-date with master and that there is some commit editing in the same files as you did, causing conflicts. What you need to do is fetching an up-to-date branch from this repo and then rebase your branch against it (and it'll always be better if you create a new branch when working on a PR). Assume this repo is called "origin" and your repo "cabello", you need to execute these commands:
|
Sorry that it took so long but let me explain why this PR was never merged and why it cannot be merged as is. First, you must know that I definitely want to fix this issue for 2.5 but you will see in a minute that it is not that simple. Everything is actually rather well explained in the phpdocs of "A role must either have a string representation or it needs to be explicitly supported by at least one AccessDecisionManager." Note the Switching to the interface as it's done here has several consequences:
That's basically why this PR cannot be merged as is, and why technically it does not cover all cases and can even introduce security issues. Now, we have several options:
Personally, I'm more in favor of the first option for several reasons:
Of course, |
I'm also in favor of option 1. This would not prevent using a toMany relation to store roles in a database if someone wants to do it. It simply means that the Is there a good way to ask the community how much they rely on this feature, to be sure that we are not just assuming it is barely used based on our own projects ? |
you could do a simple doodle http://doodle.com/vycrabazihq926yq and tweet it 👶 but of course asking about this feature |
@fabpot I'll comment the merits of your alternate options on another comment, but I'll stick to the long description of
In my specific situation, I have a Role that represents an entity in our DB. It does implement Of course you could suggest me to extend This means we still need to update a bit the code, but solution is still valid from this perspective. Next comment will bring comments over your suggested alternate solutions. |
@fabpot I'll detail each suggested alternate approach and then provide my choice.
This would bring some headache and possibly a huge BC break, but it is the best solution, by far. =) Keep the current behavior for Roles. Then, find a way to actually store the role class/object in the ACL system. Taking this solution, my previously explained suggestion would address this issue nicely, unless you are considering efforts around storing the roles in DB too. I wouldn't take this approach as it heavily increases the amount of DB calls (my internal implementation does that) and I had to customize implementation by caching the Roles elsewhere. I can't remember correctly why I had to go for Roles stored in a DB, but it was a mid-size limitation that was preventing me to use Roles as-is. If I have to choose, option 1 is the best one, but I am uncertain if my implementation would still work. |
Why are you closing this PR? |
well, you commented 5 months ago saying it was the wrong approach |
|
Commits ------- 26ff05b fixes #1538 Discussion ---------- fixes #1538 Constructor of Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity -------------------------------------------------------------------------------------------------------- currently it check if the argument is instance of Symfony\Component\Security\Core\Role\Role by ``if ($role instanceof Role)`` Maybe it should be changed to ``if ($role instanceof RoleInterface)`` Because if we use another Role class which implements RoleInterface it dosen't work when we check access, it will throw a *NoAceFoundException* when vote
We are currently storing our roles in the database, because the end user can put some permissions on the roles, that's why string-only roles are not sufficient for us. Then I hit the issue being resolved in this PR. For now I could also inherit from the |
Hi,
We are using a custom
Role
entity that's implementing theRoleInterface
, but when we tried to apply ACL on the application, someSecurityContext->isGranted
calls were denying access when they should actually allow.After checking database, our code, Symfony code, we got to the dead end where the following triple comparison was returning false:
One
$this->role
was holding our custom object that implements the RoleInterface the other$sid->getRole()
was holding a string, the strict comparison would obviously fail.After updating the constructor and tests, everything looks great.
Thanks,