-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Security] $attributes can be anything, but RoleVoter assumes strings #19725
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
maennchen
commented
Aug 24, 2016
•
edited
Loading
edited
Q | A |
---|---|
Branch? | 2.7 |
Bug fix? | yes |
New feature? | no |
BC breaks? | yes |
Deprecations? | no |
Tests pass? | yes |
Fixed tickets | #18042 |
License | MIT |
Doc PR | reference to the documentation PR, if any |
Considering this has most likely never worked, I think attributes should be hinted as string instead. |
@iltar I don't think that this is a good idea. I have a use case where i want to check if some operations (attributes) can be applied on an object (subject). For sure those operations could be flattened into a string, but one would have to parse them in the voter again which is total nonsense. Type Hinting for string would be a BC break since one can supply objects as attributes already, but only if the objects implements a |
I guess implementing |
@iltar i think its basically a good idea to allow objects there, cause in that case you can easy check if your voter is responsible or not. Like ExpressionVoter: https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Security/Core/Authorization/Voter/ExpressionVoter.php#L60 Of course you also can do that with strings, and prefix strings, and hope that there are no conflicts ... but who want this? |
I think we should not rely on the |
Otherwise you must implement your custom voter that support your custom type of attribute. |
Btw, the border between bug and new feature is really close in this case. I think it's better to consider it a new feature and submit the PR against the |
@hhamon I'd like your proposed solution. I implemented the |
I think that it's definitely a bug since the interface clearly says that mixed is accepted. (Which is currently only if you implement |
But when the attributes of a not supported type, the de decision should be abstained? |
@sstok Two times yes. |
Also |
Yes |
Should I change to check if the attribute is instance of RoleInterface instead of __toString? This will be a small BC break. |
@maennchen why exactly do you want to remove That would still be a BC break, but personally i consider it a bugfix. |
if (is_object($attribute) && !method_exists($attribute, '__toString')) { | ||
return false; | ||
} | ||
|
||
return 0 === strpos($attribute, $this->prefix); |
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.
Could be simply (string) $attribtute
as well. No need for the above statements... it should crash for invalid values by design.
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.
An attribute is mixed by design. It shouldn't crash for non string values. It should abstain. Why should it be a convention that every object passed as an attribute can be converted to a string.
I implemented a Voter, that was designed to vote for Operations on a subject when I encountered the error. Why should those operations which are not by any means strings have a toString method? That makes no sense for something that is by design mixed.
(By the way: strpos will automatically do a string casting. No string cast needed for that.)
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.
I'd change the code to check if $attribute instanceof RoleInterface
, if yes do a getRole()
on it. If it is no string or RoleInterface, I'd continue / ABSTAIN.
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.
It shouldn't crash for non string values. It should abstain
Sorry, you're right. However i think for 2.7 supportAttribute
should also consider RoleInterface
due mixed attribute support.
I refactored it with specific checks for I personally don't really care if there is support for objects having a |
@@ -57,6 +58,10 @@ public function vote(TokenInterface $token, $object, array $attributes) | |||
$roles = $this->extractRoles($token); | |||
|
|||
foreach ($attributes as $attribute) { | |||
if ($attribute instanceof RoleInterface) { | |||
$attribute = $attribute->getRole(); |
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.
We should not call supportAttribute
if the return value of getRole()
is null
as it means that there is no good representation of the role as a string.
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.
nevermind, that's already covered in supportsAttribute()
via the is_string()
check.
Thank you @maennchen. |
…mes strings (Jonatan Männchen) This PR was merged into the 2.7 branch. Discussion ---------- [Security] $attributes can be anything, but RoleVoter assumes strings | Q | A | ------------- | --- | Branch? | 2.7 | Bug fix? | yes | New feature? | no | BC breaks? | yes | Deprecations? | no | Tests pass? | yes | Fixed tickets | #18042 | License | MIT | Doc PR | reference to the documentation PR, if any Commits ------- ad3ac95 bug #18042 [Security] $attributes can be anything, but RoleVoter assumes strings