Feb 23, 2026·5 min read·32 visits
The terminal-controller-mcp package, designed to give AI models terminal access, attempted to block dangerous commands like 'mkfs' using a simple string blacklist. This CVSS 10.0 vulnerability allows attackers to bypass that check using standard shell features (e.g., specific character concatenation), leading to full Remote Code Execution (RCE).
A critical command injection vulnerability in terminal-controller-mcp allows attackers to bypass keyword-based filters and execute arbitrary code. By leveraging shell command substitution, malicious actors can reconstruct forbidden commands at runtime, rendering the application's blacklist security mechanism useless.
The Model Context Protocol (MCP) is the new hotness in the AI world. It’s essentially a standardized way for Large Language Models (LLMs) to interface with local tools, databases, and—in this specific case—your system terminal. The terminal-controller-mcp package does exactly what it says on the tin: it exposes a server that allows an AI (or anyone controlling the prompt) to execute shell commands on the host machine.
From a security perspective, this is the digital equivalent of handing a loaded shotgun to a toddler and hoping they don't pull the trigger. The premise of the tool requires exec capabilities by design. The developers knew this was risky, so they implemented a safety mechanism. They decided to act as a nanny, filtering out "bad words" before passing the command to the system shell.
Unfortunately, as history has taught us time and time again, trying to secure a shell interpreter by grepping for bad strings is a fool's errand. It’s not just a vulnerability; it’s a fundamental misunderstanding of how command shells parse input.
The core issue lies in the execute_command function. The developers implemented a blacklist—a list of specific strings that are strictly forbidden. If you try to run rm -rf / or mkfs, the Python code spots the substring, wags its finger at you, and returns a security warning.
Here is the logic flaw: Python sees a string of characters, but the Shell sees a programming language. Python checks the input statically before execution. The Shell evaluates the input dynamically during execution. If you can make the input look safe to Python but dangerous to the Shell, you win.
This is a classic "Time of Check to Time of Use" (TOCTOU) logical gap, but specifically regarding parsing context. The Python filter is looking for the literal sequence m-k-f-s. It does not understand that in Bash, $(echo mkfs) is semantically identical to mkfs.
Let's look at the vulnerable code in terminal_controller.py. It’s short, readable, and dangerously naive. It effectively tries to secure the system by checking if a substring exists within the user input.
# Inside terminal_controller.py
def execute_command(self, command: str) -> str:
# The fatal mistake: A static blacklist
dangerous_commands = ["rm -rf /", "mkfs"]
# The check
if any(dc in command.lower() for dc in dangerous_commands):
return "For security reasons, this command is not allowed."
try:
# The execution
result = subprocess.run(
command,
shell=True, # <--- The root of all evil
capture_output=True,
text=True,
timeout=timeout
)
return result.stdout
except Exception as e:
return str(e)The presence of shell=True is the final nail in the coffin. It tells Python to pass the entire string to /bin/sh (or cmd.exe) for parsing. This enables piping, redirection, and variable expansion—features that the simple if statement above completely ignores.
To exploit this, we don't need buffer overflows or heap spraying. We just need to be creative with string concatenation. We want to execute mkfs (make file system) to wipe a drive, but we can't type "mkfs".
We can use shell command substitution $() to construct the command character by character. The Python filter will see a bunch of echo commands, which aren't on the blacklist. The Shell, however, will execute the inner commands first, assemble the string, and then execute the result.
The Attack Payload:
echo "$($(echo -n m; echo -n k; echo -n f; echo -n s))"The Execution Flow:
$().echo -n m, echo -n k, etc. The result is the string mkfs.This technique is robust and works against almost any keyword-based filter that doesn't account for shell meta-characters.
Because terminal-controller-mcp is designed to run shell commands, the impact of bypassing the filter is effectively total system compromise. The severity is rated Critical (10.0) for a reason.
If this package is running inside a Docker container, the attacker has root inside that container. If the container is privileged or shares mounts with the host, escape is likely. If the user installed this locally to let their AI assistant "help with coding," the attacker now has the same permissions as that developer—access to SSH keys, source code, and AWS credentials.
This isn't just about wiping drives with mkfs. An attacker can just as easily construct a reverse shell using the same obfuscation techniques to maintain persistent access without ever triggering the "dangerous command" filter.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
terminal-controller-mcp GongRzhe | <= 0.1.7 | TBD |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-78 (OS Command Injection) |
| CVSS v3.1 | 10.0 (Critical) |
| Attack Vector | Network |
| Privileges Required | None |
| Exploit Status | Proof-of-Concept Available |
| EPSS Score | 0.00682 |
The software constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component.
CVE-2026-48597 is a high-severity Denial of Service (DoS) vulnerability in the Elixir HTTP client library Tesla (specifically involving the Mint adapter) that allows an unauthenticated remote attacker to cause an unrecoverable crash of the Erlang Virtual Machine (BEAM). The flaw arises from the dynamic conversion of untrusted URL schemes into Erlang atoms without validation, leading to global atom table exhaustion.
An Improper Encoding or Escaping of Output vulnerability (CWE-116) in elixir-tesla allowed unauthenticated remote code execution or request smuggling via unescaped Content-Disposition parameters in multipart form-data requests.
CVE-2026-49851 is a high-severity algorithmic complexity vulnerability in the Mistune Markdown parser. Under specific conditions involving dense, unmatched nesting of opening square brackets, the parser fallback loops degrade from linear execution time to a worst-case quadratic complexity. This allows unauthenticated remote attackers to trigger complete CPU exhaustion and subsequent Denial of Service with a highly compact payload.
An allocation of resources without limits or throttling vulnerability in the Elixir Mint HTTP client library allows malicious HTTP/2 servers to trigger memory exhaustion and application denial of service. The flaw exists because Mint fails to validate server-push concurrency limits during the receipt of PUSH_PROMISE frames, deferring validation to the HEADERS phase. This allows a server to reserve an unlimited number of streams in the client's memory map.
An unsafe execution vulnerability exists in the Bazar form field calculator (CalcField.php) of YesWiki prior to version 4.6.6. The application attempts to validate mathematical formulas using a complex recursive regular expression before passing them to the PHP eval() function. This design leads to both Regular Expression Denial of Service (ReDoS) and Remote Code Execution (RCE) via validation bypass.
An infinite loop vulnerability exists in the pure-Python PDF library pypdf prior to version 6.13.1. When parsing or merging a crafted PDF file containing a cyclic Article/Thread structure, the library fails to exit its traversal loop. This causes the executing thread to hang indefinitely, leading to 100% CPU utilization and a denial of service. The vulnerability is tracked under CVE-2026-54651 and GHSA-g9xf-7f8q-9mcj, with a CVSS base score of 5.5. This technical report provides a root cause analysis, code review, exploitation vectors, and mitigation paths.