ZeroHour

CVE-2026-61599

niche

Unauthenticated Arbitrary Module Import in djust WebSocket/SSE View Mounts

CVSS 4.0
8.8 high
EPSS
Published
()
Modified
AI analysis

The djust live transport resolves the LiveView to mount from a client-supplied dotted module path via Python's __import__(), and the LIVEVIEW_ALLOWED_MODULES allowlist that should restrict this is fail-open by default and loosely matched, so an unauthenticated WebSocket or SSE client can make the server import and execute the top-level code of any importable Python module. Because import runs before the LiveView subclass check and before any per-view authentication, an attacker only needs to send a mount, live_redirect_mount, or url_change frame (or an SSE mount) naming an arbitrary module. The attacker gains import-time code execution — effectively RCE-by-proxy on hosts that have a side-effectful importable module — plus denial of service via import bombs and a module/class enumeration oracle through distinct error strings. Any djust deployment exposing the WebSocket/SSE live transport is affected, including default configurations with the allowlist unset. No public proof-of-concept is known, the issue is not in CISA KEV, and no in-the-wild exploitation has been reported.

What to do: Upgrade to the patched djust release that adds the fail-closed resolution gate (is_view_import_allowed), which is applied before __import__ at all three sinks. As an interim mitigation, set LIVEVIEW_ALLOWED_MODULES to the narrow list of modules containing your mountable LiveView classes, noting this is mitigation only on pre-patch versions because the import still precedes the subclass check. Restrict network access to the WebSocket/SSE endpoints and review logs for mount frames referencing unexpected module paths, which would indicate enumeration or import abuse.

Affected
djust (PyPI project) djust
Estimated exposure
nicheLikely hundreds to low thousands of deployments (niche Django LiveView package; exact install base not published) — No install or download counts appear in the advisory; the estimate is based on djust being an emerging, niche Django LiveView framework on PyPI, with only deployments exposing the WebSocket/SSE transport network-facing being exploitable.

Order-of-magnitude estimate by the model from install counts, market share and public scan data it knows; verify before quoting.

Description

djust provides Phoenix LiveView-style reactive server-side rendering for Django with Rust-powered performance. Prior to version 1.0.7, the djust live transport resolves the LiveView to mount from a client-supplied dotted path by calling `__import__(module_path, ...)`. The module is imported — running its top-level code (import side effects) — before the framework checks that the resolved object is a `LiveView` subclass and before any per-view authentication. The `LIVEVIEW_ALLOWED_MODULES` allowlist that should contain this is fail-open (`if allowed_modules:` — skipped when the setting is unset, the framework default) and uses loose `startswith` matching. An unauthenticated WebSocket client (the WS handshake does not require auth; per-view auth runs only after import + instantiate) can therefore send a `mount` / `live_redirect_mount` / `url_change` frame (or an SSE mount) with `view = " .AnyName"` and cause the server to import — and execute the top-level code of — any importable Python module by name. Version 1.0.7 fixes the issue with a fail-closed resolution gate (`djust._view_resolution.is_view_import_allowed`): a client view path resolves only if (a) its module is already loaded (`sys.modules` — so resolving runs no new code; URL-routed views loaded by URLconf at startup keep working with zero config) or (b) it matches `LIVEVIEW_ALLOWED_MODULES` on a module-segment boundary (explicit opt-in for lazily-imported views). The gate runs before `__import__` at all three sinks (+ defense-in-depth inside `_instantiate_view`). As a workaround, set `LIVEVIEW_ALLOWED_MODULES` to the narrow list of modules that contain your mountable LiveView classes. (Note: pre-patch the allowlist is `startswith`-matched and the import still precedes the subclass check, so this is mitigation, not a complete fix.)

Ecosystems
pip
Weakness
CWE-470
Vector
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:H/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
GHSA
GHSA-7prp-2623-8g45 (high)

In the news

No ingested article mentions this CVE yet.