CVE-2026-61589 Overview
CVE-2026-61589 is a tenant isolation flaw in djust, a library that provides Phoenix LiveView-style reactive server-side rendering for Django with Rust-powered performance. Versions prior to 1.0.7 rebuild an HttpRequest on the WebSocket live path without setting HTTP_HOST, causing request.get_host() to default to "testserver". Host, subdomain, and domain TenantResolver implementations then misresolve the tenant. When STRICT_MODE=False, tenant-scoped managers return unscoped rows across tenants. When strict mode is enabled, queries return empty results and break tenancy. The flaw is classified as [CWE-348] Use of Less Trusted Source.
Critical Impact
Attackers on the WebSocket live path can trigger cross-tenant data disclosure when STRICT_MODE=False, because the reconstructed request resolves to "testserver" instead of the real Host.
Affected Products
- djust versions prior to 1.0.7
- Django applications using djust WebSocket live path with Host, subdomain, or domain TenantResolver
- Deployments configured with STRICT_MODE=False
Discovery Timeline
- 2026-09-16 - CVE-2026-61589 published to NVD
- 2026-09-16 - Last updated in NVD database
Technical Details for CVE-2026-61589
Vulnerability Analysis
The defect resides in djust's WebSocket handling code, specifically handle_mount and ViewRuntime._build_request. Both functions reconstruct an HttpRequest using Django's RequestFactory().get(...) without propagating the client-supplied Host header from the ASGI scope. Django's RequestFactory supplies a default HTTP_HOST of "testserver" when none is provided. As a result, request.get_host() returns "testserver" on every live-path request.
Tenant resolvers that key on Host, subdomain, or domain then fail to identify the calling tenant. The tenant context becomes None on the live path, while the HTTP path continues to resolve tenants correctly. This divergence between transport layers is the core of the vulnerability.
When the application runs with STRICT_MODE=False, tenant-scoped managers interpret a None tenant as an unscoped query and return rows across all tenants. This exposes data from other tenants to any authenticated user of the live path. With strict mode enabled, the same condition produces empty query results and denies legitimate access.
Root Cause
The root cause is trusting a synthetic default value in place of client-supplied transport metadata. RequestFactory is a test utility, and its default "testserver" Host is not a valid production identity. djust never extracted the real Host from the ASGI scope or validated it against ALLOWED_HOSTS.
Attack Vector
An attacker with valid credentials for any tenant establishes a WebSocket connection to a djust live view. The reconstructed request carries "testserver" as its Host, bypassing tenant scoping. In deployments with STRICT_MODE=False, the attacker retrieves records belonging to other tenants through any tenant-scoped manager query executed on the live path.
Exploitation requires network access to the live endpoint and low-privilege authentication. No user interaction is needed. See the GitHub Security Advisory GHSA-v9rj-xjfv-xj9r for full technical detail.
Detection Methods for CVE-2026-61589
Indicators of Compromise
- Application logs showing request.get_host() returning "testserver" on production WebSocket connections
- Tenant resolver logs recording None tenant context for authenticated live-path sessions
- Query logs where tenant-scoped managers return row counts inconsistent with the caller's tenant scope
Detection Strategies
- Audit WebSocket handler logs for Host values that do not appear in ALLOWED_HOSTS
- Compare tenant resolution outcomes between HTTP and WebSocket paths for the same authenticated user
- Instrument tenant-scoped managers to alert when a None tenant is used with STRICT_MODE=False
Monitoring Recommendations
- Enable verbose logging on djust ViewRuntime and handle_mount during the upgrade window
- Forward WebSocket and tenant resolver logs to a centralized SIEM or data lake for correlation
- Alert on any live-path database query returning rows tagged with tenants other than the session tenant
How to Mitigate CVE-2026-61589
Immediate Actions Required
- Upgrade djust to version 1.0.7 or later on all environments running the WebSocket live path
- Review STRICT_MODE configuration and enable strict tenant scoping where feasible
- Audit access logs for prior cross-tenant reads on live-path endpoints
Patch Information
djust 1.0.7 fixes the flaw by extracting the handshake Host from the ASGI scope and validating it against ALLOWED_HOSTS. The validation uses Django's split_domain_port and mirrors the CSWSH Origin gate, rejecting malformed Hosts at the boundary. The validated Host and TLS scheme are then propagated into the reconstructed request, so live-path tenant resolution matches HTTP. Release notes are available at GitHub Release v1.0.7.
Workarounds
- No workaround exists on the live path short of upgrading to djust 1.0.7
- Operators unable to upgrade immediately should disable the WebSocket live path and rely on the HTTP path, which resolves tenants correctly
- Confirm STRICT_MODE=True to convert cross-tenant disclosure into broken tenancy until the upgrade completes
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

