CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-61595

CVE-2026-61595: Multi-Tenancy Isolation Bypass on WebSocket and SSE Paths in djust

Amit Schendel
Amit Schendel
Senior Security Researcher

Sep 16, 2026·5 min read·2 visits

Executive Summary (TL;DR)

Prior to version 1.0.7, djust does not enforce multi-tenancy boundaries on WebSocket and SSE connection paths. Thread-local context storage is not preserved across ASGI async tasks, leading to an uninitialized tenant ID that defaults to returning unfiltered, global database results to authenticated users.

The multi-tenant isolation mechanism in djust prior to version 1.0.7 fails open on active WebSocket and Server-Sent Events (SSE) connections. Because the tenant context is stored in thread-local variables and initialized exclusively via HTTP middleware, asynchronous event loops executing ASGI/WebSocket code paths do not carry the resolved tenant identifier. When queries are executed without this context, the default database manager fails open, allowing authenticated users of any tenant to query and read sensitive rows across all other tenant accounts.

Vulnerability Overview

The djust framework provides high-performance, reactive rendering mechanisms modeled after Phoenix LiveView within Django. To maintain data boundaries in multi-tenant installations, the djust.tenants module filters database QuerySet results using a tenant identifier established during initial requests.

Traditional HTTP requests pass through standard WSGI/ASGI middleware (TenantMiddleware), which resolves and binds the tenant identifier to the current thread. However, live channels such as WebSockets and Server-Sent Events (SSE) operate outside this synchronous request-response flow. This design exposes a significant gap in state initialization for persistent, asynchronous event-driven loops.

On these asynchronous execution paths, the database queries triggered by user-driven live updates do not evaluate against the authorized tenant ID. Instead, the query manager encounters an uninitialized context and defaults to executing unrestricted, global queries. This exposes a direct path to cross-tenant data disclosure.

Root Cause Analysis

The root cause of this vulnerability lies in the combination of thread-local context storage and a fail-open query model under asynchronous execution models.

First, djust relied on threading.local() to isolate tenant data per execution thread. In modern ASGI applications, incoming connections are managed inside an asynchronous event loop, with synchronous operations offloaded to a thread pool via Django's sync_to_async wrapper. Because threads in this pool are recycled and shared dynamically across distinct async tasks, the thread-local storage is either entirely empty or polluted with context remnants from completely unrelated execution threads.

Second, the system designed the database manager to fail open when the resolved tenant context was null. Instead of raising an exception or returning an empty set when get_current_tenant() returned None, the QuerySet manager allowed the database query to proceed without filtering. This implementation design meant that any query executing within a thread lacking a tenant context bypassed all isolation constraints, as depicted in the execution flow below:

Code Analysis

The vulnerable query management logic in the djust.tenants manager was structured to fallback to an unfiltered parent query when the thread context returned None:

# Insecure implementation prior to v1.0.7
from django.db import models
from threading import local
 
_thread_locals = local()
 
def get_current_tenant():
    return getattr(_thread_locals, 'tenant_id', None)
 
class TenantManager(models.Manager):
    def get_queryset(self):
        tenant_id = get_current_tenant()
        if tenant_id is None:
            # Fails open: returns all rows across all tenants
            return super().get_queryset()
        return super().get_queryset().filter(tenant_id=tenant_id)

The fix implemented in djust version 1.0.7 migrated context tracking to contextvars.ContextVar, which natively tracks state across asynchronous tasks and coroutines. It also redesigned the manager to fail closed when STRICT_MODE is enabled:

# Remediated implementation in v1.0.7
import contextvars
from django.db import models
from django.core.exceptions import PermissionDenied
from django.conf import settings
 
# ContextVar safely tracks tenant across asynchronous coroutines
current_tenant_id = contextvars.ContextVar('tenant_id', default=None)
 
class TenantManager(models.Manager):
    def get_queryset(self):
        tenant_id = current_tenant_id.get()
        if tenant_id is None:
            # Fails closed when STRICT_MODE is True
            if getattr(settings, 'DJUST_STRICT_MODE', True):
                return super().get_queryset().none()
            # Log warning if strict mode is disabled
            return super().get_queryset()
        return super().get_queryset().filter(tenant_id=tenant_id)

Exploitation Methodology

Exploitation of this vulnerability requires an attacker to possess valid credentials for any single, low-privileged tenant account within the platform. The attacker does not need high-level administrative access or advanced permissions.

First, the attacker authenticates normally through the standard login interface. This populates their session cookie and associated authentication tokens.

Second, the attacker establishes a WebSocket connection or opens an SSE stream to the reactive djust routing endpoint. Because the connection handshake succeeds, the ASGI worker handles subsequent data-fetch events.

Third, when the attacker triggers state synchronizations or parameters updates via WebSocket payloads, the server processes these updates in a thread pool execution task. The worker executes the underlying database queries without establishing the tenant identifier in the local context. The database queries return complete, unfiltered tables. These tables are then serialized and transmitted back through the WebSocket frame to the attacker, exposing cross-tenant records.

Impact Assessment

The impact of CVE-2026-61595 is severe. In a multi-tenant software-as-a-service application, the absolute isolation of tenant data is a fundamental security contract. A failure in this boundary compromises the confidentiality of all customer records stored in the shared database.

The CVSS v3.1 base score of 7.7 represents a high-severity flaw. The Attack Vector is Network (AV:N), meaning the vulnerability can be reached remotely. Attack Complexity is Low (AC:L) as it is reproducible over standard WebSockets. Privileges Required is Low (PR:L) since any tenant authentication suffices.

The scope is marked as Changed (S:C) because the exploitation of a bug in the reactive rendering layer directly breaks isolation in the logical database access layer. The confidentiality impact is High (C:H) as all tenant tables configured with the flawed manager are readable. Because it is a read-only data disclosure bug on this specific execution path, integrity and availability scores remain None (I:N / A:N).

Remediation and Mitigation

The recommended remediation is to upgrade djust to version 1.0.7 or later, which shifts state storage to ContextVar and enforces fail-closed query behavior on WebSocket routes.

For systems that cannot be immediately updated, administrators must enforce STRICT_MODE in their Django settings. This forces the database manager to return an empty queryset (.none()) if the tenant context cannot be resolved, converting a data exposure into a service limitation.

Furthermore, developers should run the Django system check framework (python manage.py check) post-upgrade to detect any insecure configurations. This execution validates that STRICT_MODE remains active and that no critical paths bypass context verification.

Technical Appendix

CVSS Score
7.7/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N

Affected Systems

djust.tenants

Affected Versions Detail

Product
Affected Versions
Fixed Version
djust
djust-org
< 1.0.71.0.7
AttributeDetail
CWE IDCWE-636 / CWE-862
Attack VectorNetwork
CVSS v3.1 Score7.7
ImpactHigh (Confidentiality)
Exploit Statusnone
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1068Exploitation for Privilege Escalation
Privilege Escalation
CWE-636
Not Failing Securely ('Failing Open')

The software is designed to fail in a state that permits access to restricted resources when an unexpected event occurs or context is missing.

Vulnerability Timeline

Vulnerability Published
2026-09-16
Patch Released in Version 1.0.7
2026-09-16

References & Sources

  • [1]Official Advisory (GHSA-3492-cvg7-9mr2)
  • [2]Release Tag v1.0.7

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•less than a minute ago•CVE-2026-61560
9.8

CVE-2026-61560: Unauthenticated Remote Path Traversal and Access Token Exfiltration in @zereight/mcp-gitlab

CVE-2026-61560 is a critical security vulnerability in the @zereight/mcp-gitlab Server-Sent Events (SSE) server. By utilizing default, unauthenticated route setups and exposing vulnerable administrative tools, remote attackers can execute path traversal attacks to read internal process variables and hijack GitLab operations.

Amit Schendel
Amit Schendel
0 views•8 min read
•about 1 hour ago•CVE-2026-61590
7.4

CVE-2026-61590: Network-Exposed Observability Endpoints and Remote Method-Invocation in djust

A critical access control vulnerability in djust prior to 1.0.7 exposes diagnostic endpoints and remote method-invocation capabilities to unauthorized network actors. The vulnerability arises due to decoupling IP boundary validation into an opt-in middleware that was omitted from official configuration documentation, leaving views to rely solely on the status of Django's DEBUG flag.

Alon Barad
Alon Barad
2 views•7 min read
•about 3 hours ago•CVE-2025-59953
9.8

CVE-2025-59953: Unauthenticated Remote Code Execution in LMDeploy AsyncRPCServer via Insecure Pickle Deserialization

LMDeploy prior to version 0.10.2 is vulnerable to remote code execution because its AsyncRPCServer component implements unauthenticated, remote-accessible communication sockets and uses the insecure pickle.loads() deserializer to process incoming requests.

Alon Barad
Alon Barad
2 views•6 min read
•about 4 hours ago•CVE-2026-68904
7.0

CVE-2026-68904: Uncontrolled Resource Consumption (Socket Leak and Reconnection Storm) in node-opcua

CVE-2026-68904 is a high-severity Denial of Service (DoS) vulnerability in the node-opcua library. It arises from a logical flaw in the keepalive session manager combined with incorrect socket termination at the TCP transport layer. When server-side anomalies occur, affected clients fall into an infinite, high-frequency reconnection loop. Due to the use of graceful teardown (socket.end) instead of immediate termination (socket.destroy) during negotiation failures, sockets remain open in the FIN-WAIT-2 state. This accumulates system file descriptors and memory, eventually crashing the client process.

Amit Schendel
Amit Schendel
8 views•8 min read
•about 5 hours ago•CVE-2026-61593
8.1

CVE-2026-61593: Cross-Site Request Forgery in djust Server-Sent Events Transport Layer

CVE-2026-61593 is a high-severity Cross-Site Request Forgery (CSRF) vulnerability discovered in the Server-Sent Events (SSE) transport layer of djust, an open-source framework that implements Phoenix LiveView-style reactive server-side rendering for Django applications. Before version 1.0.7, a lack of origin verification on the SSE stream endpoint, combined with @csrf_exempt decorators on message POST endpoints, allowed an attacker to hijack active client sessions through cross-origin interactions.

Alon Barad
Alon Barad
5 views•5 min read
•about 6 hours ago•CVE-2026-81192
7.0

CVE-2026-81192: Local Code Execution via Untrusted Search Path in OpenTelemetry.Resources.Host

An untrusted search path vulnerability (CWE-426) in the OpenTelemetry.Resources.Host NuGet package on macOS allows a local attacker to execute arbitrary code with elevated privileges by hijacking standard system commands such as sh and ioreg.

Alon Barad
Alon Barad
4 views•6 min read