Closed (fixed)
Project:
Drupal core
Component:
user.module
Priority:
Critical
Category:
Bug report
Assigned:
Reporter:
Created:
3 Feb 2005 at 21:32 UTC
Updated:
8 Oct 2005 at 19:00 UTC
Jump to comment: Most recent file
The user_access function in user.module returns the results of the strstr() function, which returns a string, not a Boolean like the documentation suggests. This was screwing things up for me since flexinode relies on user_access for it's node_access('create'..) functionality.
The attached patch uses strpos instead of strstr. It was created from a 4.5 codebase, but I noticed that the same issue is in HEAD as well. I'm using it on my dev site, and node_access('create'..) calls are now working properly and nothing I'm using seems to have any problems with it.
| Comment | File | Size | Author |
|---|---|---|---|
| #14 | user_access_bug_0.patch | 513 bytes | killes@www.drop.org |
| #13 | user-permissions.patch | 2.83 KB | killes@www.drop.org |
| user_access_bug.patch | 473 bytes | javanaut |
Comments
Comment #1
(not verified) commented+ return strpos($perm[$account->uid], "$string, ") !== FALSE ? TRUE : FALSE;could be written more simply as
+ return strpos($perm[$account->uid], "$string, ") !== FALSE;Keep in mind it's also possible to type-cast the result of strstr to a boolean value (i.e.
return (bool) strstr($perm[$account->uid], "$string, ");)... I am unsure as to whether strstr or strpos would be faster... perhaps a quick benchmark could answer the question of which we should use.Comment #2
javanaut commentedHeh, after posting that, I realized what I had done, but never got back around to simplifying it. Good eye.
Comment #3
tangent commentedThe PHP docs claim that strpos is faster and less memory intensive than strstr.
For what it's worth, the second statement below does not seem more simple or readable than the first to me though it's hard to say if casting an int as a boolean is more or less performant than performing a logical comparison.
Comment #4
javanaut commentedThe security flaw that this fixes is where strstr finds too man positive results. Example:
module A has permission "type A create content" (Allowed for role)
module B has permission "create content" (Disallowed for role)
user_access("create content") is run for module B and returns non-FALSE, non-null results, even though the role is disallowed. Avoiding this would require a permission naming convention such that no permission were a substring of another.
Comment #5
tangent commentedPermissions are comma delimited aren't they? The comma space in the string would handle this IIRC.
Comment #6
javanaut commentedIn this example, the search string passed to strstr becomes:
"create content, "
The main list of permissions being searched would contain the string:
"type A create content, "
..which would match. This problem may not be resolved by this fix, btw.
Comment #7
tangent commentedWhile a regular expression would resolve this symptom, this example demonstrates that using only strings to identify permissions is not very robust. Is there a reason (performance would be a good one but only so far) that permissions aren't stored with an index?
Comment #8
dries commentedWould it be possible to implode() the permissions string and to use in_array() ?
Comment #9
(not verified) commentedDries: Possible, but not desirable. in_array is a rather slow function.
I'd rather put the permissions as keys of an array $perm and use isset($perm['do something']). We should then probably store serialized arrays in the table. That is ok, because the table is a sort of cache. Gerhard
Comment #10
dries commentedFine with me.
Comment #11
jonbob commentedIf we use such an array, we need to use array_key_exists() rather than isset() to avoid strict/PHP5 errors.
Comment #12
killes@www.drop.org commentedJonBob: I don't think so. If the array is defined, then we can use isset to ask if a particular index exists.
Comment #13
killes@www.drop.org commentedHere is an untested patch as proof of concept.
Comment #14
killes@www.drop.org commentedUpdated javanaut's patch according to anonymous' suggestion. A more thorough approach would be preferable of course.
Comment #15
dries commentedjavanaut: can you confirm that #14 is working for you? (This could do with being documented in the code.)
Comment #16
javanaut commentedLooks functional to me. +1
Comment #17
dries commentedjavanaut: I assume you haven't tested it yet. Because you're capable of reproducing the bug, would you mind giving this a try?
Comment #18
javanaut commentedI haven't upgraded the module that manifests this bug to CVS yet. Its functionally is identical to the patch I submitted, and I even tested this revised patch (#14) out on a 4.5.2 installation and the module in question works fine. I can test it out on 4.6rc/cvs, but it may be a small while before I upgrade the module in question. I did run it on a bare CVS installation and it is working fine for me.
Today must be bugfix Friday :)
Comment #19
Steven commentedCommitted to HEAD/4.6.
Comment #20
(not verified) commentedComment #21
(not verified) commentedComment #22
(not verified) commentedComment #23
(not verified) commentedComment #24
(not verified) commented