Not reporting against 8.x because I believe this whole thing doesn't apply to it, correct me if I'm wrong.
The 'node/%node'
route doesn't check the value/type of the path argument. So if node/3165341
is a valid node, the path node/3165341.test.1234.lol
will also load the same node.
Example, these two links load the same node:
https://www.acquia.com/node/3165341
https://www.acquia.com/node/3165341.test.1234.lol
This is because %node (node_load() --> node_load_multiple()
) uses the IN
comparison, and MySQL will cast comparisons.
As an example, take this query generated by node_load() (I modified the columns selected for clarity):
mysql> SELECT revision.vid AS vid, base.uid AS uid, revision.log AS log, revision.status AS status, revision.comment AS comment, revision.promote AS promote, revision.sticky AS sticky, base.nid AS nid, base.type AS type, base.language AS language, base.created AS created, base.changed AS changed, base.tnid AS tnid, base.translate AS translate, revision.timestamp AS revision_timestamp, revision.uid AS revision_uid FROM node base INNER JOIN node_revision revision ON revision.vid = base.vid WHERE (base.nid IN ('194.test2'));
+-----+-----+-----+--------+---------+---------+--------+-----+-------------+----------+------------+------------+------+-----------+--------------------+--------------+
| vid | uid | log | status | comment | promote | sticky | nid | type | language | created | changed | tnid | translate | revision_timestamp | revision_uid |
+-----+-----+-----+--------+---------+---------+--------+-----+-------------+----------+------------+------------+------+-----------+--------------------+--------------+
| 258 | 25 | | 1 | 1 | 0 | 0 | 194 | publication | und | 1409003246 | 1429300032 | 0 | 0 | 1429300032 | 32 |
+-----+-----+-----+--------+---------+---------+--------+-----+-------------+----------+------------+------------+------+-----------+--------------------+--------------+
1 row in set, 1 warning (0.00 sec)
mysql> SHOW WARNINGS;
+---------+------+-----------------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: '194.test2' |
+---------+------+-----------------------------------------------+
1 row in set (0.00 sec)
I believe the right fix would be to check if the values passed to node_load()
are numeric, and throw an error (404?) otherwise.
Comments
Comment #1
entendu CreditAttribution: entendu for eBay Enterprise commentedComment #2
cilefen CreditAttribution: cilefen commentedDid you test on 8.0.x? https://simplytest.me/
Comment #3
pwolanin CreditAttribution: pwolanin as a volunteer and at Acquia commentedYes, this bug has been around for lots of numeric IDs in 7 forever. Please search for existing issues.
It's not limited to nodes, but affects every entity pretty much.
I think you are actually mistaking the cause - look at:
https://api.drupal.org/api/drupal/includes%21entity.inc/function/DrupalD...
That calls intval() which is casting:
In 8, at least some routes use a regex to validate the input, but not nodes:
https://api.drupal.org/api/drupal/core%21modules%21node%21src%21Entity%2...
I'm not sure where 8 is filtering or validating.
Comment #4
entendu CreditAttribution: entendu for eBay Enterprise commentedAh, yes this has a fix in #1003788. Marking dupe.
Comment #5
pwolanin CreditAttribution: pwolanin as a volunteer and at Acquia commentedThanks for searching, but that's not actually a duplicate of this bug
Comment #6
David_Rothstein CreditAttribution: David_Rothstein as a volunteer commentedI'm pretty sure the issue @entendu linked to actually did fix this in Drupal 7.37. If you go to
node/1.test
on Drupal 7.36 you see node 1 (on MySQL), but in Drupal 7.37 and higher you get page not found.If this isn't the same issue, then what's the remaining work to do here?