Lock down the generic entity autocomplete route to logged-in users

Found while adding field_entree_liee's autocomplete: core's
system.entity_autocomplete route is '_access: TRUE' by design --
EntityQuery::accessCheck() only enforces node grants (published
status), not the base 'access content' permission, so it doesn't
respect this site's login-only lockdown the way every other route
does. Verified anonymously via plain curl that the *existing*
field_client (client taxonomy) autocomplete leaked real client names
the same way -- this isn't specific to the new field, it's a gap in
any entity reference autocomplete on the site.

hook_route_alter() doesn't exist anymore in this Drupal version
(routing moved to an event-based RoutingEvents::ALTER subscriber) --
a first attempt using the procedural hook silently did nothing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-04 12:22:26 +02:00
co-authored by Claude Sonnet 5
parent 384b283547
commit 27a799e937
2 changed files with 36 additions and 0 deletions
@@ -0,0 +1,5 @@
services:
figli_compta_ledger.route_subscriber:
class: Drupal\figli_compta_ledger\EventSubscriber\RouteSubscriber
tags:
- { name: event_subscriber }
@@ -0,0 +1,31 @@
<?php
namespace Drupal\figli_compta_ledger\EventSubscriber;
use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;
/**
* Core's generic entity autocomplete route ('system.entity_autocomplete')
* is '_access: TRUE' by design -- EntityQuery::accessCheck() only enforces
* node grants (published status), not the base 'access content'
* permission, so it doesn't actually block anonymous users the way every
* other route on this confidential site does. Discovered while adding
* field_entree_liee's autocomplete: verified the *existing* field_client
* (client taxonomy) autocomplete had the same gap, leaking real client
* names to anonymous requests via a plain curl call. Since every field on
* this content type is confidential, lock the route down site-wide rather
* than special-casing our own field.
*/
class RouteSubscriber extends RouteSubscriberBase {
/**
* {@inheritdoc}
*/
protected function alterRoutes(RouteCollection $collection) {
if ($route = $collection->get('system.entity_autocomplete')) {
$route->setRequirement('_permission', 'access content');
}
}
}