GitHub Advisoryadvisory · PyPI

GHSA-xx4j-w367-7247 djust authentication bypass: a login_required / on_mount LiveView mount redirect does not close the WebSocket, allowing an unauthenticated client to dispatch event-handler calls

HIGH Published 2026-08-25 Modified 2026-08-25 Official page ↗
Aliases
CVE-2026-55571
Ecosystem
PyPI
Packages
djust
Severity
High
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
Weaknesses
CWE-285, CWE-306
Reviewed
2026-08-25

Affected packages

• PyPI djust: < 1.0.4 → fixed in 1.0.4

Description

Impact djust's `LiveViewConsumer` mounts a `LiveView` over a WebSocket. When a view is gated (`login_required` / `permission_required`, or an `on_mount` hook that returns a redirect) and the connecting user is not authorized, the consumer sent the client a `{"type":"navigate","to":...}` redirect frame and then `return`ed — without closing the socket and without clearing `self.view_instance`. Only the `PermissionDenied` branch closed the connection (`close(4403)`). A real browser obeys the navigate frame and leaves, hiding the problem. A raw WebSocket client that ignores the redirect keeps an open, mounted socket. Because `handle_event` did not re-check authentication/authorization after mount, that client could then send `{"type":"event", ...}` frames and invoke any `@event_handler` method on the gated view with no authenticated session — an authentication bypass on the live mutation path. Who is affected: apps that expose `LiveView`s gated by `login_required` / `permission_required` / a redirecting `on_mount` hook, where the gated view's event handlers perform sensitive reads or mutations and do not independently re-verify the user. Exploitation requires a non-browser WebSocket client and knowledge (or enumeration) of the view path and event names. Patches Fixed in djust 1.0.4 (commit `1ae8aa9`, PR #1780). Both the auth-redirect and `on_mount`-hook-redirect branches of `handle_mount` now send the navigate frame and then `close(code=4403)` and clear `self.view_instance`, mirroring the existing `PermissionDenied` branch. Public / authorized mounts are unchanged. The same path is reachable via `handle_live_redirect_mount` (which delegates to `handle_mount`) and is covered by the same fix. 1.0.4 also adds an opt-in defense-in-depth control, `LIVEVIEW_CONFIG['reauth_on_event'] = True` (default OFF), which re-resolves the user from the session and re-runs the view's auth check on every event for gated views. Workarounds Upgrade to 1.0.4. If you cannot upgrade immediately, on affected versions ensure that every `@event_handler` on a gated `LiveView` independently verifies the request user is authenticated and authorized (e.g. check `request.user.is_authenticated` / permissions at the top of each handler), since the framework does not re-check after mount on `", ...}` frame reaches the handler and executes it without an authenticated session. On 1.0.4 the socket is closed with code `4403` immediately after the redirect and the event frame is rejected. (Regression test: `tests/test_ws_auth_close_socket.py`.) Credits Discovered internally during the djust v1.1.0 WebSocket-auth security review.

Related

Alias · CVE (1)

  • CVE-2026-55571 djust provides Phoenix LiveView-style reactive server-side rendering for Django with Rust-powered performance. vulnerability

Weakness · CWE (2)

  • CWE-285 Improper Authorization weakness
  • CWE-306 Missing Authentication for Critical Functionality weakness

References