Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessAuthenticate to multi-tenant djust app
-
DeliveryOpen live-view over WebSocket
-
ExploitReconstructed request omits Host, resolves to 'testserver'
-
ExecutionTenantResolver returns None, scoping disabled
-
ImpactRead unscoped cross-tenant rows
Vulnerability Assessment
| Weakness |
CWE
ASVS 5.0
V6 - Authentication IP-independent access control
|
| Exploitation Conditions | Requires a djust deployment (version < 1.0.7) configured for multi-tenancy using host-, subdomain-, or domain-based TenantResolvers, AND the setting STRICT_MODE=False for the cross-tenant DISCLOSURE outcome; with the default STRICT_MODE the same flaw only breaks tenancy (empty queryset), not leaks. Exploitation occurs specifically on the WebSocket 'live path' (handle_mount / ViewRuntime._build_request), which rebuilds the request via RequestFactory().get(...) without HTTP_HOST. Limiting factors: an authenticated user must open the live-view mount (PR:L), the multi-tenant host-resolver architecture must be in use, and the disclosure worst case depends on the non-default STRICT_MODE=False; the ordinary HTTP path resolves tenants correctly and is unaffected. The only remediation on the live path is upgrading to 1.0.7 - there is no configuration workaround. |
| Impact | This is a moderate-severity, low-real-priority multi-tenancy flaw. The vendor CVSS 3.1 vector (AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:N/A:N = 6.3) is internally coherent and I concur with it: network-reachable over the WebSocket live path, but AC:H reflects that impactful cross-tenant disclosure only occurs under a non-default configuration (STRICT_MODE=False) combined with host/subdomain/domain TenantResolvers, and PR:L reflects that an authenticated client must open the live-view mount. Under the default STRICT_MODE the same bug degrades to an empty queryset (broken tenancy / availability of data to the legitimate tenant), not disclosure - so the C:H worst case is conditional. No EPSS score, no CISA KEV entry, and no public POC were provided, and no SSVC decision data was supplied. There is no signal of active exploitation. The confidentiality impact is real (cross-tenant data leakage in a multi-tenant deployment) but the compounding preconditions (multi-tenant host-based resolver + STRICT_MODE disabled + authenticated live-path access) keep realistic risk well below the raw score. Treat as a routine patch-and-verify item, prioritized only for operators running djust multi-tenancy with STRICT_MODE=False. |
| Exploit ScenarioDerived | In a djust multi-tenant deployment using host/subdomain TenantResolvers with STRICT_MODE=False, an authenticated user opens a live-view over WebSocket; because the reconstructed request carries no Host header and defaults to 'testserver', tenant resolution returns None and the tenant-scoped managers return unscoped rows, exposing other tenants' records to that user's session. No public exploit code was identified at time of analysis, and the attack requires the specific non-default multi-tenant configuration. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Sep 16, 2026
Cross-tenant data exposure on the djust live WebSocket path affects installations before 1.0.7 that use host-, subdomain-, or domain-based TenantResolvers for multi-tenancy. Because the request rebuilt by handle_mount and ViewRuntime._build_request carries no client Host, get_host() falls back to "testserver", so the tenant resolves to None on the live path even though the ordinary HTTP path resolves it correctly; with STRICT_MODE=False the tenant-scoped managers then return unscoped rows and an authenticated user can read other tenants' data. With the default STRICT_MODE the identical flaw only yields empty querysets (broken tenancy, no disclosure). No public exploit code exists and there is no confirmed active exploitation; EPSS/KEV data were not provided, and the CVSS vector (AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:N/A:N, 6.3) reflects the high attack complexity and the dependency on an explicit STRICT_MODE=False configuration.
RemediationAI
Vendor-released patch: djust 1.0.7. Upgrade all djust installations to 1.0.7 or later, after which the ASGI handshake Host is validated against ALLOWED_HOSTS and propagated with the TLS scheme into the reconstructed request so live-path tenant resolution matches HTTP; see the advisory at https://github.com/djust-org/djust/security/advisories/GHSA-v9rj-xjfv-xj9r and the release at https://github.com/djust-org/djust/releases/tag/v1.0.7. The vendor states plainly that there is no workaround on the live path short of upgrading, so treat the version bump as the only definitive fix. Where immediate patching is impossible, actionable compensating controls are: first, confirm STRICT_MODE is left at its default (not False) - this reduces the flaw from cross-tenant disclosure to broken tenancy (empty querysets and failed mounts on the live path) and carries the operational trade-off that tenant-scoped views may appear empty or error for live users; second, migrate tenant resolution away from Host/subdomain/domain TenantResolvers to path- or session-based resolution for as long as the unpatched version is running, which prevents the None-tenant fallback but requires an architectural change and coordinated URL/routing updates; and third, since exploitation requires an authenticated user (PR:L) able to open a live-view mount, restrict access to live-view endpoints to fully trusted accounts until the upgrade completes. Note that neither compensating control is a substitute for upgrading, and that with the default STRICT_MODE the residual risk is availability/functionality rather than disclosure.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in pypi
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
djust is a Python/Django live-view framework (CPE pkg:pip/djust) that rebuilds an HttpRequest on the WebSocket path via RequestFactory().get(...) inside handle_mount and ViewRuntime._build_request. That synthetic request never set HTTP_HOST, so Django's request.get_host() fell back to the literal "testserver", which is the CWE-348 (Use of Less Trusted Source) root cause: a hardcoded placeholder was consulted instead of the authoritative Host from the ASGI connection scope. Host-, subdomain-, and domain-based TenantResolvers downstream of that value therefore saw no usable host and misresolved the active tenant to None, while the same resolver chain on the HTTP request path - where the real Host header is present - behaved correctly. The consequence is conditional: the default (strict) tenant-manager behavior produced an empty queryset and broke tenancy silently, whereas STRICT_MODE=False removed the tenant filter entirely and returned rows across all tenants. The fix in 1.0.7 extracts the handshake Host from the ASGI scope, validates it against Django's ALLOWED_HOSTS using the same gate logic already applied to the CSWSH Origin check (parsing with Django's split_domain_port so malformed or spoofed Hosts are rejected at the boundary), and propagates that Host together with the TLS scheme into the reconstructed request, making live-path tenant resolution identical to the HTTP path. The scope-change component (S:C) and confidentiality-only impact (C:H/I:N/A:N) in the assessed vector reflect that the flaw leaks data within the framework's tenant boundary but grants no write or code-execution capability.
Know when Django gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:N/A:N
Network live-path access with authenticated mount (PR:L); AC:H because impactful disclosure needs multi-tenant host resolvers plus non-default STRICT_MODE=False; S:C for crossed tenant boundary, C:H disclosure only, no integrity/availability impact.
Primary rating from Vendor (https://github.com/djust-org/djust).
CVSS VectorVendor: https://github.com/djust-org/djust
Lifecycle Timeline
1DescriptionCVE.org
Impact
The WebSocket handle_mount and ViewRuntime._build_request rebuild an HttpRequest via RequestFactory().get(...) with no HTTP_HOST, so request.get_host() defaulted to "testserver" on the live path. Host/subdomain/domain TenantResolvers then misresolved the tenant - None on the live path while the HTTP path resolved correctly. With STRICT_MODE=False the tenant-scoped managers returned unscoped rows (cross-tenant disclosure); with the default they returned an empty queryset (broken tenancy).
Patches
Fixed in djust 1.0.7. The handshake Host is extracted from the ASGI scope, validated against ALLOWED_HOSTS (the same logic as the CSWSH Origin gate, parsed with Django's split_domain_port so malformed Hosts are rejected at the boundary), and propagated - with the TLS scheme - into the reconstructed request, so live-path tenant resolution matches HTTP exactly.
Workarounds
No workaround on the live path short of upgrading. Most exposed when combined with STRICT_MODE=False.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Information disclosure occurs when an application unintentionally exposes sensitive data that aids attackers in reconnaissance or directly compromises security.
The package python/cpython from 0 and before 3.6.13, from 3.7.0 and before 3.7.10, from 3.8.0 and before 3.8.8, from 3.9
In Django 1.10.x before 1.10.8 and 1.11.x before 1.11.5, HTML autoescaping was disabled in a portion of the template for
An issue was discovered in Django 3.2 before 3.2.14 and 4.0 before 4.0.6. Rated critical severity (CVSS 9.8), this vulne
Django 3.1.x before 3.1.13 and 3.2.x before 3.2.5 allows QuerySet.order_by SQL injection if order_by is untrusted input
Django before 1.11.27, 2.x before 2.2.9, and 3.x before 3.0.1 allows account takeover. Rated critical severity (CVSS 9.8
An authentication/authorization bypass in the djust Python live-view framework (versions prior to 1.0.7) lets unauthenti
Unauthenticated arbitrary Python module import in djust before 1.0.7 lets any client that can reach the WebSocket or SSE
Django 1.11 before 1.11.29, 2.2 before 2.2.11, and 3.0 before 3.0.4 allows SQL Injection if untrusted data is used as a
Cross-site scripting (XSS) vulnerability in the dismissChangeRelatedObjectPopup function in contrib/admin/static/admin/j
Forged content modification in django-page-cms through 2.0.13 lets unauthenticated remote attackers exploit five CSRF-ex
Cross-site request forgery in djust's Server-Sent-Events transport affects all versions prior to 1.0.7 and allows a cros
Unauthenticated remote attackers can read live Django view and session state and invoke server-side handlers through dju
EUVD-2026-81306
GHSA-v9rj-xjfv-xj9r
NVD
CVE.org
EPSS
VulDB
Exploit-DB