From 4f4dba9d51b9979dbfb67c9223fc794439d558d8 Mon Sep 17 00:00:00 2001 From: RinCodeForge927 Date: Sat, 17 Jan 2026 20:17:09 +0700 Subject: [PATCH 1/2] [Security] Fix potential command injection on Windows in CLI dev command --- src/mcp/cli/cli.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/mcp/cli/cli.py b/src/mcp/cli/cli.py index c4cae0dce3..39fe8b977c 100644 --- a/src/mcp/cli/cli.py +++ b/src/mcp/cli/cli.py @@ -3,6 +3,7 @@ import importlib.metadata import importlib.util import os +import shlex import subprocess import sys from pathlib import Path @@ -275,8 +276,15 @@ def dev( # Run the MCP Inspector command with shell=True on Windows shell = sys.platform == "win32" + cmd_args = [npx_cmd, "@modelcontextprotocol/inspector"] + uv_cmd + + if shell: + # On Windows with shell=True, I need to quote arguments to prevent injection + # and join them into a single string, as passing a list with shell=True is unsafe/undefined behavior + cmd_args = " ".join(shlex.quote(arg) for arg in cmd_args) + process = subprocess.run( - [npx_cmd, "@modelcontextprotocol/inspector"] + uv_cmd, + cmd_args, check=True, shell=shell, env=dict(os.environ.items()), # Convert to list of tuples for env update From b6a0419397b94bb86d36fa54b57bd1caf708e940 Mon Sep 17 00:00:00 2001 From: Rin Date: Fri, 23 Jan 2026 19:21:38 +0700 Subject: [PATCH 2/2] Switch from shlex.quote to subprocess.list2cmdline for Windows support. I noticed that shlex.quote uses single quotes which cmd.exe doesn't handle correctly. Switched to list2cmdline to ensure proper escaping when shell=True is used on Windows. Also removed the unused shlex import. --- src/mcp/cli/cli.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mcp/cli/cli.py b/src/mcp/cli/cli.py index 39fe8b977c..1635d3b829 100644 --- a/src/mcp/cli/cli.py +++ b/src/mcp/cli/cli.py @@ -3,7 +3,6 @@ import importlib.metadata import importlib.util import os -import shlex import subprocess import sys from pathlib import Path @@ -281,7 +280,8 @@ def dev( if shell: # On Windows with shell=True, I need to quote arguments to prevent injection # and join them into a single string, as passing a list with shell=True is unsafe/undefined behavior - cmd_args = " ".join(shlex.quote(arg) for arg in cmd_args) + # Using list2cmdline as it's the correct way to escape for cmd.exe + cmd_args = subprocess.list2cmdline(cmd_args) process = subprocess.run( cmd_args,