Install

Works with Drupal: ^10.3 || ^11

Using Composer to manage Drupal site dependencies

Alternative installation files

Download tar.gz 30.5 KB
MD5: 0562070d3ba70dbac01f78bed4ff8ad1
SHA-1: 2a29c09c6abd1d7dd5f3d10ce11b537a546e9e66
SHA-256: 7faa5b92023f2e39d1b52e91b24e07802c5fa963fd32d240180e0812b1c8540f
Download zip 47.06 KB
MD5: 491777e62997d800ffb5b44f26fc2d0a
SHA-1: 1d993454196ccee32013781e10e57e44a0252846
SHA-256: de4e39b91c5f917a137648d21228a6f6db83459b72b114a03c01535c475f224b

Release notes

Recommended upgrade for all 1.0.0-beta1 users. Fixes a security-relevant correctness bug surfaced by field testing on TubeSpanner Portal: the response subscriber was emitting X-LiteSpeed-Cache-Control: public,max-age=N and X-LiteSpeed-Tag on responses that Drupal had explicitly marked uncacheable (admin pages, authenticated user pages, anything with Cache-Control: private, no-cache, or no-store).

Severity

Latent rather than active. LSWS bypasses caching when it sees a session cookie or Cache-Control: private, so no actual cache poisoning has been observed. Beta1 has been shipping the misleading directive and tags for the duration of beta1's life. The risk is that a future LSWS configuration change weakening cookie-based bypass would have caused authenticated admin responses to cache for the configured TTL with user:N cache tags, which could have served one logged-in admin's response to other users via a tag-purge race.

The fix

The response subscriber now defers to Drupal's HTTP cacheability decision via Symfony\Component\HttpFoundation\Response::isCacheable() before emitting any LSCache header. Because the subscriber runs at priority -999 (after Drupal's FinishResponseSubscriber has finalised Cache-Control), the check reflects Drupal's real decision: status code, Cache-Control directives, and Vary headers all considered.

Five new unit tests cover the cacheable, private, no-cache, no-store, and disabled-module paths in the subscriber.

Verification

To confirm the fix on your install:

  1. Authenticate as an admin user.
  2. Run curl -sI -A "Mozilla/5.0" -b cookiejar.txt against any admin route, direct to origin (bypassing CDN if applicable).
  3. Expected: no x-litespeed-tag or x-litespeed-cache-control headers in the response.
  4. Compared to beta1: those headers were present with public,max-age=N and a tag list including user:N entries.

Upgrade notes

No configuration changes needed. Composer-update to 1.0.0-beta2, run drush cr, verify per the section above. Anonymous public pages continue to receive headers as before; only previously-misleading admin/authenticated paths change.

Caveats

Still beta. Production-ready for early adopters who can monitor; soak time before 1.0.0 stable continues.

Credit for the discovery: TubeSpanner Portal admin via field testing.

Created by: dinis
Created on: 25 Apr 2026 at 09:38 UTC
Last updated: 25 Apr 2026 at 09:38 UTC
Bug fixes

Other releases