Stop the Mercure hub from accepting anonymous subscribers - #287
Conversation
An unauthorised subscription was answered 200 OK and then received nothing, so a Studio tab whose cookie had expired kept a healthy looking stream with no live updates at all. Answering 401 makes that state visible and recoverable. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Closing for consistency with pimcore/demo-enterprise#528. The skeleton itself ships neither Direct Edit nor Portal Engine, so the change is safe as it stands - but both bundles are commonly added to a skeleton install, and Portal Engine's Direct Edit status indicator subscribes to the hub without a token ( Keeping The actual fix for pimcore/platform-version#346 is pimcore/studio-ui-bundle#4009, which re-authorizes on every reconnect; this hardening was defence in depth on top of it. |
Part of the fix for pimcore/platform-version#346.
Problem
MERCURE_EXTRA_DIRECTIVES: anonymouslets the hub accept a subscription that carries no validmercureAuthorizationcookie. Such a subscription is answered200 OKand then silentlyreceives nothing, because every update Studio publishes is a private update.
That turns an authorisation problem into invisible data loss. A Studio tab whose cookie expired
(it lives one hour; the tab lives as long as the user leaves it open) keeps what looks like a
perfectly healthy stream while notifications, job progress and agent chat events are all dropped,
with no error anywhere, until the page is fully reloaded. Measured on a real installation, a tab
ran in that state for five hours across ~31 reconnects.
Change
Drop the
anonymousdirective. An unauthorised subscription now gets401, which the client cansee and react to. Nothing in Pimcore subscribes to the hub anonymously: Studio always holds a
cookie, and pimcore/studio-ui-bundle#4009 makes every reconnect renew it and retry.
Verification
Started
dunglas/mercurewithMERCURE_EXTRA_DIRECTIVES: ''and probed it:anonymous)200 OK, private update not delivered401200 OK, delivered200 OK, delivered401401The hub starts cleanly with an empty directive list, and authorised delivery is unchanged.
Not included
The demo ships
.docker/nginx.conf; the skeleton ships one too, and in both thelocation /hubblock has no SSE specific proxy settings (proxy_buffering off,proxy_read_timeout,proxy_http_version 1.1). That is worth a separate look, but it is adifferent concern from this bug and is deliberately left out of this PR: measurements showed the
hub's ~40s heartbeat keeps the stream inside nginx's default 60s idle timeout, so it is hardening
rather than a fix.