Platforms

Drupal

Drupal announces itself in an `X-Generator` header of the form `Drupal 10 (https://www.drupal.org)`, which names the major version, and through its `/sites/default/files/` paths and settings script. Core also sets two security headers without being asked: `X-Content-Type-Options: nosniff`, and `X-Frame-Options: SAMEORIGIN` unless one is already present. When cacheability debugging is enabled, responses gain `X-Drupal-Cache-Tags` and `X-Drupal-Cache-Contexts` headers.

How the engine recognises it

A generator meta tag naming Drupal — weight 95.

An `X-Generator` header naming Drupal — weight 90.

`/sites/default/files/` paths or the `drupal-settings-json` script — weight 70.

Any one of the three is enough; the header alone reports with confirmed confidence.

The X-Generator header

Drupal core's response subscriber sets `X-Generator` to `Drupal <version> (https://www.drupal.org)` on main responses.

The code takes the part of the version before the first dot, so the header names the major version only.

It is an inventory fact rather than a vulnerability; whether the major version is still supported is the question to ask.

It can be removed with custom code or at a proxy, and removing it does not hide Drupal's paths.

Headers core sets by itself

Core's finish-response subscriber sets `X-Content-Type-Options: nosniff` on responses.

It sets `X-Frame-Options: SAMEORIGIN` when the response does not already carry an X-Frame-Options header.

A Drupal site therefore usually passes those two header checks without any configuration, and fails them only if something downstream strips them.

Other security headers — HSTS, Content-Security-Policy — are not added by core and need configuring.

Cache debugging headers

When cacheability debugging is enabled, core exposes the cache tags and contexts of each page in `X-Drupal-Cache-Tags` and `X-Drupal-Cache-Contexts` headers.

They are a development aid and reveal internal structure — entity types, identifiers, configuration names.

On a production site they indicate a development setting left enabled.

They are reported with the other internal details found in responses.

The same debugging mode adds an `X-Drupal-Cache-Max-Age` header stating the computed maximum age of the page.

Which checks apply

`technology.inventory` lists Drupal with its evidence; `technology.versions` shows a version only when one is parsed from a generator meta tag, never from a guess.

`security.x_content_type_options` and `security.x_frame_options` confirm the two headers core sets.

`security.csp` and `transport.hsts` report the headers core does not set.

`security.server_disclosure` reports product and version strings in response headers.

Cache headers core adds

When a response may not be cached — because a policy forbids it or the configured page cache maximum age is zero — core declares it non-cacheable in `Cache-Control` and sets an `Expires` date of 19 November 1978, a value chosen to be long past.

When caching is allowed and the maximum age is above zero, core adds its default cacheable `Cache-Control`, unless the controller already set one.

The page cache module adds an `X-Drupal-Cache` header of `HIT` or `MISS` on responses it is allowed to cache for anonymous visitors.

An `Expires` header in 1978 is therefore not a clock error on a Drupal site; it is how core says do not cache.

These headers make Drupal's caching decisions unusually readable from outside, which the cache checks use directly.

For authenticated and personalised pages, the dynamic page cache module adds an `X-Drupal-Dynamic-Cache` header — `HIT`, or `UNCACHEABLE` with the reason — which tells the same story for pages that anonymous caching cannot serve.

Frequently asked questions

Why does my Drupal site pass the X-Frame-Options check without configuration?
Because core sets X-Frame-Options: SAMEORIGIN itself when no such header is present, and X-Content-Type-Options: nosniff too.
Does X-Generator reveal my exact Drupal version?
It names the major version in the form `Drupal 10 (https://www.drupal.org)`, not the full release number.
What are X-Drupal-Cache-Tags headers?
A cacheability debugging aid that exposes internal cache metadata. They should not appear on a production site.

Sources

Related

VeriFixScan crawls a site and applies its checks to every page it reaches, keeping the evidence behind each finding. Scanning one website is free.

Scan a website