Back to Blog
high SEVERITY7 min read

How Unbound Thread Allocation Denial of Service happens in Python Engine.IO and how to fix it

A high-severity vulnerability (CVE-2026-48802) in python-engineio 4.12.2 allowed attackers to exhaust system resources through unbound thread allocation, leading to denial of service. The fix upgrades the dependency to version 4.13.2, which implements thread pool limits to prevent resource exhaustion attacks against real-time WebSocket applications.

O
By Orbis AppSec
Published August 6, 2026Reviewed August 6, 2026

Answer Summary

CVE-2026-48802 is an unbound thread allocation vulnerability in python-engineio 4.12.2 that can cause denial of service (DoS) through resource exhaustion, classified under CWE-770 (Allocation of Resources Without Limits or Throttling). The vulnerability allows attackers to force the server to create unlimited threads by opening numerous concurrent connections. The fix upgrades python-engineio from 4.12.2 to 4.13.2, which introduces thread pool management and connection limits to prevent unbounded resource allocation.

Vulnerability at a Glance

cweCWE-770 (Allocation of Resources Without Limits or Throttling)
fixUpgrade to python-engineio 4.13.2 which implements bounded thread pools and connection rate limiting
riskAttackers can exhaust server resources by forcing unlimited thread creation through concurrent connections
languagePython
root causepython-engineio 4.12.2 lacks thread pool limits for handling concurrent WebSocket/polling connections
vulnerabilityUnbound Thread Allocation Denial of Service

Introduction

In a Python application using real-time WebSocket communication, we discovered a high-severity vulnerability (CVE-2026-48802) in the poetry.lock dependency file. The vulnerable package, python-engineio version 4.12.2, contained an unbound thread allocation flaw that could allow attackers to exhaust server resources and cause a complete denial of service. This vulnerability is particularly dangerous for applications handling real-time communication, where each connection could potentially spawn new threads without limits.

The issue was identified through Trivy security scanning, which flagged the vulnerable python-engineio version in the dependency tree. While the vulnerability wasn't confirmed as directly reachable through the application's code paths, its presence in the dependency chain represented a significant security risk that needed immediate remediation.

The Vulnerability Explained

Python Engine.IO is a widely-used library that provides real-time bidirectional communication between clients and servers, supporting both WebSocket and HTTP long-polling transports. The vulnerability in version 4.12.2 stems from the library's thread management approach when handling concurrent client connections.

Here's what made python-engineio 4.12.2 vulnerable:

# Conceptual representation of the vulnerable pattern in python-engineio 4.12.2
# Each new connection could spawn a new thread without checking resource limits
def handle_new_connection(client_id, transport):
    # No thread pool limit - creates new thread for each connection
    thread = threading.Thread(target=process_client, args=(client_id,))
    thread.start()  # Unbounded thread creation

The core issue is that python-engineio 4.12.2 would create new threads to handle incoming connections without enforcing a maximum thread count. An attacker could exploit this by:

  1. Opening massive concurrent connections: Using a simple script, an attacker opens thousands of WebSocket or long-polling connections to the server
  2. Forcing thread creation: Each connection triggers the creation of a new thread to handle that client
  3. Exhausting system resources: As threads accumulate, they consume memory, CPU context-switching overhead, and file descriptors
  4. Causing system failure: Eventually, the system runs out of resources, crashes, or becomes completely unresponsive

Real-world attack scenario: Imagine an application using python-engineio for a real-time chat feature. An attacker writes a script that opens 10,000 simultaneous connections to the chat endpoint. Without thread limits, the server attempts to create 10,000 threads, each consuming approximately 8MB of stack space (80GB total), plus heap memory for connection state. The server's memory is exhausted within seconds, causing the application to crash and denying service to all legitimate users.

The impact is severe because:
- No authentication required: Attackers can launch this attack before authentication checks
- Low attack complexity: Simple scripts using tools like websocket-client can generate thousands of connections
- Cascading failures: Resource exhaustion can affect other services on the same host
- Difficult to recover: Once resources are exhausted, the application may need manual intervention to restart

The Fix

The fix addresses CVE-2026-48802 by upgrading python-engineio from version 4.12.2 to 4.13.2. This upgrade introduces critical thread management improvements that prevent unbounded resource allocation.

Before (python-engineio 4.12.2):

# poetry.lock excerpt showing vulnerable version
[[package]]
name = "python-engineio"
version = "4.12.2"
# No thread pool limits, unbounded allocation possible

After (python-engineio 4.13.2):

diff --git a/poetry.lock b/poetry.lock
index d80adcc2..08240396 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand.
+# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand.

The upgrade to python-engineio 4.13.2 includes:

  1. Bounded thread pools: Implements a configurable maximum thread count using ThreadPoolExecutor with a max_workers parameter
  2. Connection queuing: When thread limits are reached, new connections are queued rather than creating additional threads
  3. Graceful degradation: The server can reject connections with appropriate error messages when at capacity, rather than crashing
  4. Resource monitoring: Better internal tracking of active threads and connections

The changes were made to two files:
- pyproject.toml: Updated to specify the minimum safe version of python-engineio
- poetry.lock: Regenerated to lock in version 4.13.2 with its security fixes

This specific fix is particularly effective because it:
- Preserves functionality: All valid client connections continue to work normally
- Adds safety bounds: Prevents resource exhaustion without requiring application code changes
- Maintains performance: Thread pooling actually improves performance under high load compared to unbounded thread creation
- Reduces attack surface: Makes it significantly harder for attackers to exhaust server resources

The Poetry lock file update also shows additional dependency adjustments, including the addition of mutagen packages with platform-specific markers, ensuring the entire dependency tree is secure and compatible.

Key Takeaways

  • python-engineio 4.12.2 specifically lacks thread pool limits, allowing attackers to force unbounded thread creation through concurrent connections to Engine.IO endpoints
  • Upgrading to python-engineio 4.13.2 is essential as it introduces bounded thread pools and connection management that prevent resource exhaustion attacks
  • The vulnerability exists in the dependency tree even if not directly called, making dependency scanning with tools like Trivy critical for identifying hidden risks in poetry.lock
  • Thread-based concurrency models require explicit resource limits - never create threads in unbounded loops based on external input
  • Real-time communication libraries (WebSocket, Socket.IO, Engine.IO) are high-value DoS targets and require special attention to connection limits and resource management

How Orbis AppSec Detected This

  • Source: External client connections to Engine.IO/Socket.IO endpoints accepting WebSocket and HTTP long-polling transports
  • Sink: Thread creation routines in python-engineio 4.12.2 that spawn worker threads for each incoming connection without enforcing maximum limits
  • Missing control: No thread pool bounds or connection rate limiting in python-engineio 4.12.2, allowing unlimited thread allocation
  • CWE: CWE-770 (Allocation of Resources Without Limits or Throttling)
  • Fix: Upgraded python-engineio from 4.12.2 to 4.13.2, which implements bounded thread pools and connection limits

Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.

Conclusion

CVE-2026-48802 demonstrates how seemingly innocuous dependency versions can harbor critical security vulnerabilities. The unbound thread allocation issue in python-engineio 4.12.2 could have allowed attackers to completely disable services through resource exhaustion, affecting all users of the application. By upgrading to version 4.13.2, the application now benefits from proper thread pool management and connection limits that prevent this entire class of attacks.

This incident reinforces the importance of continuous dependency monitoring, automated security scanning, and rapid patching of known vulnerabilities. For applications using real-time communication libraries, implementing multiple layers of resource protection—thread pools, connection limits, rate limiting, and monitoring—is essential for maintaining availability under attack conditions.

Prevention and further reading

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #158

Related Articles

critical

deleteNestedProperty Prototype Pollution via Dot-Notation Path

The `deleteNestedProperty` function in propertyUtils.ts allowed attackers to manipulate JavaScript object prototypes by passing specially crafted dot-notation paths like `__proto__.polluted`. A fix now blocks dangerous keys before processing, preventing prototype pollution attacks that could affect all objects in the application.

high

How Denial of Service via Infinite Loop Happens in JavaScript Dependencies and How to Fix It

CVE-2026-67213 is a high-severity denial of service vulnerability in nanoid before version 5.1.6 that triggers an infinite loop during random ID generation when processing specially crafted input. We upgraded nanoid across the entire dependency tree to patch this flaw and prevent attackers from freezing application threads. This fix ensures that ID generation remains resilient even when handling adversarial input patterns.

high

How Sensitive Data Exposure happens in Zotero plugins and how to fix it

A high-severity data exposure vulnerability in `Zotero.ts` automatically transmitted complete document metadata—including private notes, attachment paths, and tags—to external LLM services without user consent. The fix replaces broad `item.toJSON()` serialization with explicit field selection, sending only essential bibliographic data.

high

How missing dependency update cooldowns happen in GitHub Dependabot configurations and how to fix it

A semgrep scan flagged `.github/dependabot.yml` for lacking a cooldown period, meaning Dependabot would immediately propose updates to brand-new package versions across npm, Bundler, and Docker ecosystems. The fix adds a `cooldown: default-days: 7` block to every `package-ecosystem` entry, forcing a one-week waiting period before newly published releases are considered — reducing exposure to malicious or unstable package drops.

high

How Path Traversal Happens in TensorFlow's Data Service and How to Fix It

TensorFlow's data service dispatcher validated dataset IDs against forward-slash traversal attacks but overlooked backslash characters on non-Windows platforms, allowing attackers to escape the root directory. A targeted fix adds explicit backslash validation across all platforms, closing a high-severity path traversal vulnerability in the snapshot management system.

critical

How Unbounded WebSocket Message Handling Causes Resource Exhaustion in Node.js and How to Fix It

The WebSocketCrossServerAdapter class in a popular Node.js WebSocket library lacked any rate limiting on inbound messages, allowing attackers to flood Redis nodes and WebSocket servers with high-volume traffic. The fix introduces a configurable `rateLimit` option that caps messages per connection per second, preventing resource exhaustion while preserving legitimate functionality.