Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Is this a security hole? A security weakness? An unfixable flaw of our current system? The patch exposes the addTag method of db_select fame for EntityFieldQuery. Easy... until you realize that if you query just by field value then you might get back any type of entities and so you do not have and can not have the entity base table to access control. You think "oh, entity_load will take care of the access control when I load nodes" -- not so fast. Entity loading does not do access control. Is that a security hole? A security weakness? Hmm :)
Anyways, here is the patch that adds addTag.
Comment | File | Size | Author |
---|---|---|---|
#35 | the_ugliest_sql_query_of_drupal_7_3.patch | 16.06 KB | dixon_ |
#33 | the_ugliest_sql_query_of_drupal_7_2.patch | 16.07 KB | dixon_ |
#32 | the_ugliest_sql_query_of_drupal_7.patch | 13.65 KB | chx |
#25 | the_ugliest_sql_query_of_drupal_7.patch | 12.43 KB | chx |
#18 | the_ugliest_sql_query_of_drupal_7.patch | 13.3 KB | chx |
Comments
Comment #1
bjaspan CreditAttribution: bjaspan commentedsubscribe
Comment #2
aspilicious CreditAttribution: aspilicious commentedAlmost did it correct from the first try ;)
One small newline needed
Comment #3
jhodgdonI am +1 on adding the ability to add tags to EntityFieldQuery.
What aspilicious is saying is that there should be a blank line between @param and @return in docblocks. The doc could be cleaned up a bit in other ways too, but it's clear enough.
As far as it being a security hole, maybe we should put something into the doc header for the class about that?
Also, there is no taxonomy tag for queries, or at least there is no taxonomy query alter function that I can see on api.drupal.org.
Anyway, here's a new patch. The only difference is documentation...
Hmmm....
Take a look at http://api.drupal.org/api/function/node_query_node_access_alter/7
In order to use the query tag, you also need meta data. So there also needs to be an addMetaData method on this query.
Anyway, here's some cleaned up doc, but the code needs work still.
Comment #4
jhodgdonSee http://api.scratch.drupal.org/api/drupal/includes--database--query.inc/f... for more on addMetaData
Comment #5
jhodgdonAlso for an example of usage, NodeQueryAlter::testNodeQueryAlterLowLevelWithAccess() in modules/node/node.test has an example.
Comment #6
chx CreditAttribution: chx commentedAfter a discussion with jhodgdon we have agreed that
entity_load_with_access_control($entity_type, $ids = array(), $conditions = array(), $tags = array(), $metadata = array(), $reset = FALSE)
six arguments, ouch.Comment #7
chx CreditAttribution: chx commentedComment #8
jhodgdonAgreed with the above. I can help on the documentation part for sure.
Comment #9
Crell CreditAttribution: Crell commentednode_load() has had no access restrictions for nearly a decade and we've not considered that a security hole. Why exactly do we now need even that to be filtered? Or am I misunderstanding how far this is going to go?
Comment #10
jhodgdonHmmm. Are you saying that the node queries that respected node access in the past didn't go through node_load()?
Comment #11
jhodgdonSorry, didn't mean to change the priority on you crell.
But It does need to be CNW, since if we are adding addTag we still need meta data too.
Comment #12
chx CreditAttribution: chx commentednode_load surely did not have access control but this is node_load_multiple. A world of a difference.
Comment #13
Crell CreditAttribution: Crell commentedI didn't mean to change the priority either. Bah! :-)
I just talked with chx a bit in AIM. I'm fine with adding default access restriction to X_load_multiple(), just not to X_load(). It sounds like the plan is to add access restriction methods to the controllers with no defaults, and then X_load_multiple() will be hard coded with a sane set of default restriction markers (eg, node_access tag). If you want a different set, call entity_get_controller() yourself and do your own thing. That sounds good to me.
The caveat is that controllers are not designed to be disposable action objects the way SelectQuery is. That is, the controller persists from one query to the next. So what happens if you call NodeController->addTag('foo')->load(1), and then later on call NodeController->load(2), and then later call NodeController->addTag('bar')->load(3)? How do we tell that the tags/metadata/etc. are from an "old query"? The edge cases here are interesting to say the least... :-)
My best idea at the moment is for load() to end by wiping any such settings. So you could do NodeController->addTag('foo')->addTag('bar')->load(1), and then the next time you call NodeController->... it would have no tags since you already called load() once.
But then there's still the question of entity caching. I'll let someone else figure that bit of excitement out...
Comment #14
chx CreditAttribution: chx commentedAs for node_load_multiple itself I do not want to access control that, what I meant is that this family of funcitonality needs access control because it's multiple. But, most of the time you have the nid listing query in SQL and access controlled itself and it'd be a waste to access control the load itself then. It's a rare but necessary thing to access control a load. And so we will add the necessary functionality accessible by calling entity_get_controller() and methods.
Comment #15
catchI'm not sure what's being suggested with node_load_multiple(), but that case is what node_access() is for, entity loading and listing are not the same thing, and I want entity_load() to not take $conditions at all in D8.
Comment #16
Damien Tournoud CreditAttribution: Damien Tournoud commentedWe definitely don't want to do any access control during the loading process. Access control belong in the query, not in the process of loading the objects. For example: you cannot correctly page the data if you haven't performed the access control beforehand.
This said, it seems possible to implement proper access control here. But we have to understand that the access control (that belong in the query) will have to be implemented differently for each query mechanisms.
In core, we only have to deal with field_sql_storage. This means that we need to:
<entity_name>_access
tag to the SQL query generated byEntityFieldQuery::propertyQuery
. Because we start the query from the base table, it should work transparently.field_entity_access
tag to the SQL query generated byfield_sql_storage_field_storage_query()
. This one is slightly more tricky, because in the case of field-only queries (where the entity type is not specified in the query), all the access control mechanism needs to kick-in at the same time. Each of them will have to do the access control conditionally on the etid of the row. For node_access, for example, it means having aLEFT JOIN {node_access} na ON ($base_table_alias.etid = :node_etid AND na.nid = $base_table_alias.entity_id)
, and having a similar check on the entity type in the condition.It will probably not be that pretty (even if I'm convinced that we can implement that with only very minor changes to node_query_node_access_alter()), but we really need to do this.
Comment #17
jhodgdonI think all that is really being suggested is to put addTag/addMetaData capability on queries that are attempting to list entities.
The patch above adds addTag (and needs to also have addMetaData) on the field storage query.
chx (I believe) is also suggesting adding the capability of tags to the low-level entity controller's querying capabilities. He isn't suggesting adding it by default to entity_load, but just giving the entity controller class/interface the ability to have tags if someone wants to call the lower-level functions when they are doing a combined query/load using conditions.
And in both cases, the idea is also to document that access checks are not being done by default, so if you need access checks, you should use addTag.
Comment #18
chx CreditAttribution: chx commentedI agree with Damien because if you add access control to the loader then paging is shot. You ask for ten results and at the end of the day end up with none because all you got from your query is denied? That's not good.
This patch amends the [query conditions AND node access conditions] node access function to [query conditions AND ((entity is node AND node access conditions) OR (entity is not node)]. Given that already the node access conditons were ugly, adding some AND / OR does not particularly help. Hence the patch name. (Damien said it won't be pretty. Clairvoyant.)
It also adds tag and metadata capabilities to EntityFieldQuery. Comes with a test. Tons of documentation.
Comment #19
jhodgdonThis all looks fairly reasonable, except I'm not sure about this bit inside EntityFieldQuery::propertyQuery()
Why automatically add the node_access tag? There are sometimes reasons for doing queries where you might not want to check node access (such as during cron runs, where user is anonymous but you might need to act on nodes anonymous wouldn't have permission to see), and with this added, it seems like you are forcing the query to add node access restrictions whether they're wanted or not. Or am I missing something?
Comment #20
paddy_deburca CreditAttribution: paddy_deburca commentedIs the
addMetaData
function missing areturn $this;
? This should be required to be consistent with the documentation:@return EntityFieldQuery * The called object.
should be
Paddy.
Comment #21
Farhang Darzi CreditAttribution: Farhang Darzi commentedaddtag_efq.patch queued for re-testing.
Comment #22
Farhang Darzi CreditAttribution: Farhang Darzi commented#18: the_ugliest_sql_query_of_drupal_7.patch queued for re-testing.
Comment #23
Farhang Darzi CreditAttribution: Farhang Darzi commented#3: 860180-betterdoc.patch queued for re-testing.
Comment #25
chx CreditAttribution: chx commentedThanks for the comments. Rerolled against HEAD with the changes asked for in #19 and #20.
Comment #26
moshe weitzman CreditAttribution: moshe weitzman commentedtested this a bit and it works as described by DamZ and implemented by chx. i tested by enabling node_access_test module (using drush) and viewed the url: /node_access_test_page.
code and docs look good as well.
as a followup, chx mildly agreed to add a test which adds access control for users (e.g. hide all 'executive role' users) and does a user field query which applies those conditions. that would be great for testing and API documentation.
Comment #27
webchickLIVE from Drupalcon CPH! I couldn't quite figure what this code was doing, so I started looking at the tests.
This seems like it has a high probability of false-triggering when tests are expanded later, and it's also not obvious what's going on. Can we prefix with "[node_access_test]" or something?
This whole setUp() function could generally use a few comments to explain what we're setting up here and why.
I don't understand where that "node test view" permission is actually used? There's no special allotment done in the node creation process... How do these tests pass at all right now?
(minor) weird stray blank lines here.
Is there a reason we don't just do "N nodes"? That seems like it'd simplify this code quite a bit.
Is that strictly necessary? Won't the testbot report if exceptions were encountered, just as it reports back if notices were encountered? If not, we should probably fix.
Powered by Dreditor.
Comment #28
dixon_I'll try to address webchick's issues in the patch from #25 to get this ready.
Comment #29
webchickSo, I think this is the first place I'm lost. Under what circumstances does a function called _node_query_something something have something other than a node coming into it? I "saw" node_query_node_access_alter() and node_query_entity_field_access_alter() and that didn't help me out at all.
Can we flesh these comments out with an example of some kind? And/or, better yet, reflect it in the tests?
Powered by Dreditor.
Comment #30
webchickOops. I cross-posted. :( Sorry, dixon_!
Comment #31
dixon_No problem :)
Comment #32
chx CreditAttribution: chx commentedHere is the original problem fixed: node module got better comments. LOT better comments. Edit: and variable names. I have written more lines of code but oh well.
Comment #33
dixon_I've got some major newtwork issues here in CPH. But here is the patch finally. chx improved the comments in node.module. So this patch only contains some comment improvements in node.test and some minor code style issues that webchick mentioned.
Comment #34
dixon_Comment #35
dixon_Moshe gave a review and found a double space in the comments. Now fixed.
Comment #36
moshe weitzman CreditAttribution: moshe weitzman commentedRTBC. This was green before and all we changed was Doxygen but I guess we should still wait for green before commit.
Comment #37
zzolo CreditAttribution: zzolo commentedPatch looks good, and running test locally pass.
Comment #38
zzolo CreditAttribution: zzolo commentedUnintentionally set back to needs review. Network issues.
Comment #39
Dries CreditAttribution: Dries commentedReviewed it and it looks good. Committed to CVS HEAD. Thanks!