- Issue created by @dokumori
- 🇳🇱Netherlands dokumori Utrecht
Comments by @srees:
---
We are converting as many of our tables as possible to support mb, and also adjusting the code in node.module's node_save function to prevent future issues that may arise:
~~~~~~~
if ($node->is_new) {
/*
* Database insertion errors with either revisions or the node tables cascade into every
* module that hooks into node_insert, and finally the node_access table
* via the call to node_access_acquire_grants($node) below, where we may end
* up with new rows where nid=0, which grants anonymous permission to view
* all nodes protected by a node_access module.
*/
$success = FALSE;//We want to fail safe
_node_save_revision($node, $user->uid);
//when creating a node, we should *always* have a vid, or there was a DB error
if($node->vid) {//do not attempt to write to node if the vid is missing
$success = drupal_write_record('node', $node);//if this works, $success = 1
}
if(!$success){
watchdog('node', 'Failed to insert node: ' . db_error(), [], WATCHDOG_ERROR);
drupal_set_message('Failed to insert node, please contact an administrator for assistance.');
if($node->vid) {//if the revision saved but the node didn't, we should remove the revision record
db_query('DELETE FROM {node_revisions} WHERE vid = %d', $node->vid);
}
drupal_goto('');
exit();
}
db_query('UPDATE {node_revisions} SET nid = %d WHERE vid = %d', $node->nid, $node->vid);
$op = 'insert';
}
~~~~~~~~~~~~
---Further note: settings.php $db_collation is not set. Setting it to $db_collation = 'utf8mb4_unicode_520_ci'; prevents the issue as the database will accept that (regardless if the mysql collation is actually the same). Outside of my realm of expertise how that all works.
---
Comments by @dsnopek
I was able to partially reproduce this on D6.
I was testing with the 'nodeaccess' module, using a content type that disallowed anonymous users. On inserting a new node that had an emoji in the body, it would fail to fully create the node: a row is added to the node table with vid = 0, but no row is added to the node_revisions table. This meant the node was broken, and couldn't be viewed by anyone. However, the entry on the 'node_access' table looks correct, so there's actually no security implication.
Perhaps the security part of this comes from the way that 'og_access' works?
In any case, this is definitely a bug: the node shouldn't be considered successfully created if the row can't be added to the node_revisions table, and it should abort early.
---
Comments by @srees:
I think what may be different in the og_access case is that og_access does not create an entry in the node_access table for all cases. If the node being generated is not within its realm, it will not generate a node_access row, and then Drupal defaults to create a row on its own for node=0.
I believe og_access is correct in not defining an access row if the node is not under its control.