djust.tenants isolation was enforced only on the HTTP path. The current tenant was stored in threading.local() and set exclusively by the HTTP-only TenantMiddleware, so on the live (WebSocket/SSE) path get_current_tenant() was always None during mount and every event handler — and the tenant-aware QuerySet manager failed OPEN (returned the unfiltered queryset, ignoring STRICT_MODE), disclosing every tenant's rows to whoever held the socket. threading.local was additionally shared across connections on the sync_to_async executor thread.
Fixed in djust 1.0.7. Tenant storage moved to a contextvars.ContextVar (per async task); the resolved tenant is bound around WS/SSE mount and every dispatch; both managers scope the base queryset once and fail CLOSED (.none() under the default STRICT_MODE); and system check S006 warns when STRICT_MODE=False.
No workaround on the live path short of upgrading.
{
"cwe_ids": [
"CWE-636",
"CWE-862"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-16T15:32:10Z",
"nvd_published_at": null,
"severity": "HIGH"
}