Problem/Motivation

File Gate reports two security findings on the status report from file_gate_requirements() in file_gate.install:

  • a gated field that stores files on a public file system, so the gate never runs;
  • a named secret that has a value but no field scope, so it can authenticate and mint nothing.

Drupal 11.3 replaced the procedural hook with hook_runtime_requirements(), hook_update_requirements() and an install-time class. Core now logs this on every container rebuild:

file_gate_requirements without a #[LegacyRequirementsHook] attribute is deprecated in drupal:11.3.0 and removed in drupal:13.0.0. See https://www.drupal.org/node/3549685

The notice is the small part. Drupal 13 stops calling the procedural hook, and nothing fails when that happens: the two findings leave the status report and the site reads as healthy. A check that guards a security boundary should not be able to disappear without an error.

The module's tests would not catch it. They call file_gate_requirements('runtime') directly, so they pass whether or not core ever invokes the function.

Steps to reproduce

  1. Install File Gate 1.9.2 on Drupal 11.4.
  2. Rebuild the container, or run any kernel test that enables the module, with deprecations shown.
  3. The notice above is logged for file_gate_requirements.

Proposed resolution

The module already requires Drupal 11.4, so it does not need the legacy attribute or a transition period.

  • Move both checks to a hook class that implements hook_runtime_requirements(), with the entity type manager and the secret registry injected.
  • Remove file_gate_requirements(). It only ever acted in the runtime phase.
  • Use RequirementSeverity::Error in place of the REQUIREMENT_ERROR constant, which is deprecated since 11.2.
  • Change the tests to invoke the hook through the module handler, the way the status report does, so they fail if the hook stops being called.

Remaining tasks

  • Patch and tests.
  • Review.

User interface changes

None. The two status report rows keep their keys, titles, severity and text.

API changes

file_gate_requirements() is removed. It was a hook implementation, not a public API. Code that called it directly should invoke runtime_requirements through the module handler.

Data model changes

None.

Comments

jmcerda created an issue. See original summary.

  • jmcerda committed 88fd64a6 on 3624429-runtime-requirements-hook
    test: make the requirements tests fail when the hook is not implemented...

  • jmcerda committed 08b8ad4b on 1.x
    fix: move the security status checks to hook_runtime_requirements()...
jmcerda’s picture

The fix is on 1.x (comment #3). Both status report findings now come from hook_runtime_requirements() in Drupal\file_gate\Hook\FileGateRequirements, and file_gate_requirements() is gone. Keys, titles, severity and text are unchanged.

Checked on Drupal 11.4.6 with a public field deliberately marked as gated: drush core:requirements reports file_gate_public_gated_fields at Error, naming the field. The deprecation notice for file_gate_requirements no longer appears.

One commit is still to land (comment #2). On 1.x the two tests that assert no finding can pass even if the hook is never invoked, because the module handler returns NULL for a module with no implementation and the tests treated that as an empty list. The commit makes them assert that the implementation exists. It also adds #[RunTestsInSeparateProcesses] to the last kernel test without it, which Drupal 12 requires. I will set this to Fixed when that is on 1.x.

After updating, rebuild caches (drush updatedb or drush cr): the compiled container lists the removed function until it is rebuilt.

  • jmcerda committed 88fd64a6 on 1.x
    test: make the requirements tests fail when the hook is not implemented...
jmcerda’s picture

Status: Active » Fixed

Both commits are on 1.x: the move to hook_runtime_requirements() (comment #3) and the test follow-up (comment #5). The requirements tests now assert that the implementation exists, so they fail if the hook stops being called; with the #[Hook] attribute removed, all four fail. Every kernel test in the project carries #[RunTestsInSeparateProcesses].

Setting this to Fixed. It will be in the next 1.x release. Rebuild caches after updating.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.