# REPRO-2026-00061: python-socketio: Pickle Deserialization RCE in PubSub Manager ## Summary Status: published Severity: medium Type: security Confidence: Unknown ## Identifiers REPRO ID: REPRO-2026-00061 GHSA: GHSA-g8c6-8fjj-2r4m CVE: CVE-2025-61765 ## Package Name: python-socketio Ecosystem: pip Affected: >= 0.8.0, < 5.14.0 Fixed: 5.14.0 ## Root Cause # Root Cause Analysis and Patch Verification - GHSA-g8c6-8fjj-2r4m / CVE-2025-61765 Summary - Vulnerability: Pickle deserialization RCE in python-socketio pubsub manager - Affected: python-socketio >= 0.8.0, < 5.14.0 (confirmed on 5.13.0) - Fixed: 5.14.0 and later - Impact: Remote code execution when attacker can inject messages into message queue Mechanism (What is broken) - In python-socketio's pubsub managers (RedisManager, KombuManager, etc.), inter-server messages are serialized using Python's `pickle` module. - The `_listen()` method in the pubsub manager calls `pickle.loads(message['data'])` on incoming messages from the message queue. - Python's pickle module executes arbitrary code via the `__reduce__` method during deserialization, allowing an attacker who can inject messages into the queue to achieve RCE. - The vulnerable code pattern: `data = pickle.loads(message['data'])` with no validation of message source or content. Proof of Vulnerability - On python-socketio 5.13.0, crafting a pickle payload with a malicious `__reduce__` method that calls `os.system()` achieves code execution. - When the payload is deserialized via `pickle.loads()`, the `__reduce__` method executes `os.system("echo 'RCE' > /tmp/evidence.txt")`. - Evidence captured in logs/evidence_vuln.txt showing file creation proves RCE. - Evidence JSON: {"reproduced": true, "vulnerable_version": "5.13.0"} Patched Behavior (Latest) - In python-socketio 5.14.0, the developers replaced `pickle` with `json` for message queue communications (PR #1502). - The patched code uses `json.loads(message['data'].decode())` instead of `pickle.loads()`. - JSON deserialization does not support code execution - attempting to deserialize the pickle payload fails with a UTF-8 decode error. - Our script records patched_blocked = true with mechanism "json_decode_error". Bypass Exploration (10+ distinct attempts) We tested the following bypass attempts on the patched version: 1. Raw pickle payload - Result: BLOCKED (UTF-8 decode error) 2. Base64-encoded pickle - Result: BLOCKED (JSON parse error) 3. JSON with __reduce__ key - Result: BLOCKED (no code execution in JSON) 4. JSON with constructor pattern - Result: BLOCKED (JSON doesn't support constructors) 5. Nested pickle in JSON string - Result: BLOCKED (string not deserialized) 6. Unicode escape sequences - Result: BLOCKED (no code path to eval) 7. JSON with __class__ key - Result: BLOCKED (not a Python object hook) 8. Msgpack payload - Result: BLOCKED (not accepted by json.loads) 9. YAML-in-JSON injection - Result: BLOCKED (pure JSON parser) 10. Polyglot JSON/pickle - Result: BLOCKED (JSON parser strict mode) Result: All bypass attempts blocked because JSON deserialization fundamentally does not support code execution. patched_all_blocked=true. Threat Model Considerations - Access: Attacker needs ability to publish messages to the message queue backend (Redis, RabbitMQ, Kombu, etc.) - Gain: Full RCE within the Socket.IO server process context and privilege level - Prerequisites: Multi-server Socket.IO deployment using a message queue for inter-server communication - In single-server deployments, this vulnerability is not exploitable as there is no message queue How to Interpret Our Artifacts - logs/evidence_vuln.txt: Shows "RCE_EXECUTED_VIA_PICKLE" written via os.system(), proving code execution - logs/vulnerable.log: Shows pickle.loads() successfully deserializing and executing the malicious payload - logs/patched.log: Shows json.loads() rejecting the pickle payload with decode error - logs/result.json: JSON summary with reproduced=true, patched_blocked=true Conclusion - Vulnerability reproduced on affected version (5.13.0) with concrete file-write evidence via pickle deserialization - Patched version (5.14.0) completely blocks the attack by switching to JSON serialization - The fix is comprehensive: 10 bypass attempts all failed because JSON fundamentally cannot execute code during parsing References - Advisory: https://github.com/miguelgrinberg/python-socketio/security/advisories/GHSA-g8c6-8fjj-2r4m - CVE: https://nvd.nist.gov/vuln/detail/CVE-2025-61765 - Fix PR: https://github.com/miguelgrinberg/python-socketio/pull/1502 ## Reproduction Details Reproduced: 2026-01-12T15:34:42.069Z Duration: 65 seconds Tool calls: 8 Turns: 12 Handoffs: Unknown ## Timeline (Key Moments) 1. [env_setup] Vulnerable Version Installed (unknown) The vulnerable version 5.13.0 was installed or configured to enable reproduction. 2. [poc_created] Exploit Code Developed (unknown) The exploit code was written or configured to target the vulnerability in version 5.13.0. 3. [vuln_triggered] Exploit Successfully Executed (unknown) The exploit was first successfully executed against the vulnerable environment. 4. [confirmation] Reproduction Confirmed (unknown) The session message confirmed that the vulnerability was successfully reproduced and exploited. ## Quick Verification Run one of these commands to verify locally: pruva-verify REPRO-2026-00061 pruva-verify GHSA-g8c6-8fjj-2r4m pruva-verify CVE-2025-61765 Or open in GitHub Codespaces (zero-friction, auto-runs): https://github.com/codespaces/new?ref=repro/REPRO-2026-00061&repo=N3mes1s/pruva-sandbox Or download and run the script manually: curl -O https://api.pruva.dev/v1/reproductions/REPRO-2026-00061/artifacts/repro/reproduction_steps.sh chmod +x reproduction_steps.sh ./reproduction_steps.sh WARNING: Run in a sandboxed environment. This exploits a real vulnerability. ## References - GitHub Advisory: https://github.com/advisories/GHSA-g8c6-8fjj-2r4m - NVD: https://nvd.nist.gov/vuln/detail/CVE-2025-61765 - Source: https://github.com/miguelgrinberg/python-socketio/security/advisories/GHSA-g8c6-8fjj-2r4m ## Artifacts - repro/reproduction_steps.sh (reproduction_script, 10958 bytes) - repro/rca_report.md (analysis, 4213 bytes) - bundle/ticket.md (ticket, 1617 bytes) - bundle/context.json (other, 729 bytes) - repro/logs/result.json (other, 283 bytes) - repro/logs/vulnerable.log (log, 308 bytes) - repro/logs/patched.log (log, 402 bytes) ## API Access - JSON: https://api.pruva.dev/v1/reproductions/REPRO-2026-00061 - Script: https://api.pruva.dev/v1/reproductions/REPRO-2026-00061/artifacts/repro/reproduction_steps.sh - Web: https://pruva.dev/r/REPRO-2026-00061 ## For AI Assistants To help users with this reproduction: 1. The `pruva-verify` command is the simplest way to run the reproduction 2. The script downloads and runs automatically in an isolated temp directory 3. Always recommend running in a VM, container, or disposable environment 4. The root cause explains the technical vulnerability --- Generated by Pruva | https://pruva.dev