Say, I have a query that selects nodes using an OR expression. For example:
db_rewrite_sql("SELECT n.nid FROM {node} n WHERE n.created > 123456789 OR n.updated > 123456789");
Now, this query doesn't make much sense, but is very well possible to build a sensible query with some joined tables and an OR.
When I run this query through db_rewrite_sql I expect the resulting query to only ever return nodes the user has access to. Take a look at what the resulting query is:
SELECT DISTINCT(n.nid) FROM {node} n INNER JOIN {node_access} na ON na.nid = n.nid WHERE (na.grant_view >= 1 AND ((na.gid = 0 AND na.realm = 'all'))) AND n.created > 123456789 OR n.updated > 123456789
so
SELECT ... WHERE [node access] AND n.created > 123456789 OR n.updated > 123456789
As you can see, this query will return nodes that have been updated after 123456789 whether the user can access them or not.
Two possible solutions:
- document the fact that you should always add brackets to the expression after WHERE when using
db_rewrite_sql; - make
db_rewrite_sqladd brackets to the existing WHERE expression before appending additional stuff.
This bug applies at least to Drupal 4.7 and 5.0.
| Comment | File | Size | Author |
|---|---|---|---|
| #11 | db_rewrite_sql_head_1.patch | 1.25 KB | decafdennis |
| #10 | db_rewrite_sql_head_0.patch | 1.41 KB | decafdennis |
| #6 | db_rewrite_sql_bench.csv | 7.55 KB | decafdennis |
| #5 | db_rewrite_sql_47.patch | 1.88 KB | decafdennis |
| #4 | db_rewrite_sql_head.patch | 1.86 KB | decafdennis |
Comments
Comment #1
chx commentedCritical because of the security implications.
Comment #2
chx commentedBetter patch :)
Comment #3
decafdennis commentedAbove patches don't fix this issue.
I'm working on a patch, if that doesn't appear to be a viable solution we'll document the needed parentheses.
Comment #4
decafdennis commentedHere's a patch, the whole of the $where and $join insertion logic is changed. It doesn't look very pretty, but it works.
I tested it reasonably extensive and it seems to rewrite all queries correctly. Only difference with what the current function produces is whitespace and the added parentheses to the existing WHERE part. I even did some quick benchmarking using 20000 samples for 14 different queries, and in the worst case scenario (there is already a WHERE and just LIMIT was used, not GROUP BY or ORDER BY) the new function takes about 4% longer.
Here are patches for HEAD and DRUPAL-4-7 and my extremely scientific benchmark results.
Comment #5
decafdennis commentedPatch for 4.7.
Comment #6
decafdennis commentedPrimitive benchmark.
Comment #7
decafdennis commentedDeclared evil by chx.
Comment #8
cog.rusty commentedYes... the time is not right for meta-rewrites.
Comment #9
chx commentedNot evil , but the code is really ugly. Sorry. Whether this can or need to be fixed in Drupal 5 is not mine to decide.
Comment #10
decafdennis commentedI do know it's ugly, I said so myself it isn't pretty.
Here's another one using a regular expression. Not much prettier I must say. I still need to have some
ifs because there's no such thing as conditional backreferencing or anything like that. I need to determine whether to add AND, for example.Comment #11
decafdennis commentedThis time a pretty patch, conceived by chx.
Comment #12
decafdennis commentedSame patch can and should be used for 4.7.
+1 from me, I've already patched my production site (jantinbergencollege.nl) and it works great.
Comment #13
dries commentedI committed this patch to CVS HEAD, although it could do with more testing. There are lots of small corner cases so hopefully we find any bugs real soon.
It should probably be backported to Drupal 4.7 once it has been proven to be rock stable.
Comment #14
pwolanin commentedFor 5.x, Modr8 uses db_rewrite_sql() to prevent nodes in moderation from being listed at /node, in the tracker, etc. (but is not actually a node access module). This patch seems to work fine with Modr8.
Comment #15
dries commentedWe're also testing this patch on groups.drupal.org now ... so far it seems to work with OG but the site might be a little too busy to tell for sure ...
Comment #16
dries commentedNo problems in more than 24 hours -- looks good. I'm going to switch the version.
Comment #17
killes@www.drop.org commentedapplied
Comment #18
(not verified) commented