GongRzhe/YOLO-MCP-Server
criticalNo description
MCP server (purpose undetermined)
1125@mcp.tool()
1126def comprehensive_image_analysis(
1127 image_path: str,
1128 confidence: float = 0.25,
1129 save_results: bool = False
1130) -> Dict[str, Any]:
1131 ...
1132 try:
1133 if not os.path.exists(image_path):
1134 return {"error": f"Image file not found: {image_path}"}
1135
1136 # Load image
1137 image = load_image(image_path, is_path=True)// Exploitable if MCP is exposed to untrusted prompts (network_exposed) or by a compromised LLM (local_only).
The comprehensive_image_analysis tool accepts an arbitrary file path via the image_path parameter and reads the file using PIL's Image.open. There is no validation to restrict the path to a specific directory, allowing an attacker to read any file on the system that the server process has access to.
ImpactAn attacker could read sensitive files such as /etc/passwd, SSH keys, or application secrets by providing their paths as image_path.
FixRestrict image_path to a specific allowed directory (e.g., ./images) and validate that the resolved path stays within that directory. Use os.path.abspath and check against a whitelist.
174@mcp.tool()
175def detect_objects(
176 image_data: str,
177 model_name: str = "yolov8n.pt",
178 confidence: float = 0.25,
179 save_results: bool = False,
180 is_path: bool = False
181) -> Dict[str, Any]:
182 ...
183 try:
184 # Load image (supports path or base64)
185 image = load_image(image_data, is_path=is_path)// Exploitable if MCP is exposed to untrusted prompts (network_exposed) or by a compromised LLM (local_only).
The detect_objects tool accepts an image_data parameter that can be a file path when is_path=True. The load_image function (line 79-102) opens the file using PIL.Image.open without any path validation, allowing arbitrary file reads.
ImpactAn attacker could read any file on the system by setting is_path=True and providing a path like /etc/passwd as image_data.
FixRestrict file paths to a specific allowed directory. Validate that the path is within an allowed scope before opening.
1262@mcp.tool()
1263def analyze_image_from_path(
1264 image_path: str,
1265 model_name: str = "yolov8n.pt",
1266 confidence: float = 0.25,
1267 save_results: bool = False
1268) -> Dict[str, Any]:
1269 ...
1270 try:
1271 # Call detect_objects function with is_path=True
1272 return detect_objects(
1273 image_data=image_path,
1274 model_name=model_name,
1275 confidence=confidence,
1276 save_results=save_results,
1277 is_path=True
1278 )// Exploitable if MCP is exposed to untrusted prompts (network_exposed) or by a compromised LLM (local_only).
The analyze_image_from_path tool directly passes the user-supplied image_path to detect_objects with is_path=True, which reads the file without any path validation.
ImpactSame as above: arbitrary file read.
FixRestrict image_path to an allowed directory.
522@mcp.tool()
523def validate_model(
524 model_path: str,
525 data_path: str,
526 imgsz: int = 640,
527 batch: int = 16
528) -> Dict[str, Any]:
529 ...
530 # Validate model path
531 if not os.path.exists(model_path):
532 return {"error": f"Model file not found: {model_path}"}
533
534 # Validate dataset path
535 if not os.path.exists(data_path):
536 return {"error": f"Dataset not found: {data_path}"}// Exploitable if MCP is exposed to untrusted prompts (network_exposed) or by a compromised LLM (local_only).
Both validate_model and export_model accept model_path and data_path parameters and check their existence with os.path.exists. They also load the model file using get_model which reads the file. No path validation is performed.
ImpactAn attacker could read arbitrary .pt files or probe for existence of any file.
FixRestrict model_path and data_path to allowed directories.
459@mcp.tool()
460def train_model(
461 dataset_path: str,
462 model_name: str = "yolov8n.pt",
463 epochs: int = 100,
464 imgsz: int = 640,
465 batch: int = 16,
466 name: str = "yolo_custom_model",
467 project: str = "runs/train"
468) -> Dict[str, Any]:
469 ...
470 # Validate dataset path
471 if not os.path.exists(dataset_path):
472 return {"error": f"Dataset not found: {dataset_path}"}// Exploitable if MCP is exposed to untrusted prompts (network_exposed) or by a compromised LLM (local_only).
The train_model tool accepts a dataset_path parameter and checks if it exists using os.path.exists. While it does not read the file content directly, the existence check can be used for information disclosure (path existence oracle). Additionally, the path is later passed to model.train which may read files from that path.
ImpactAn attacker could probe for existence of arbitrary files on the system, and potentially read files if the training process accesses them.
FixRestrict dataset_path to a specific allowed directory.
929@mcp.tool()
930def start_camera_detection(
931 model_name: str = "yolov8n.pt",
932 confidence: float = 0.25,
933 camera_id: int = 0
934) -> Dict[str, Any]:
935 ...
936 # Start detection thread
937 camera_running = True
938 camera_last_access_time = time.time()
939 camera_thread = threading.Thread(
940 target=camera_detection_thread,
941 args=(model_name, confidence, 30, camera_id),
942 daemon=True
943 )
944 camera_thread.start()// Exploitable if MCP is exposed to untrusted prompts (network_exposed) or by a compromised LLM (local_only).
The MCP server provides tools to start, stop, and read camera detections. This allows an attacker to activate the camera without any user interaction or consent, which is a privacy violation.
ImpactAn attacker could spy on the user by activating the camera and reading frames via get_camera_detections.
FixRequire explicit user confirmation before starting the camera, or remove camera functionality from the MCP server.
110def get_model(model_name: str = "yolov8n.pt") -> YOLO:
111 """Get or load YOLO model from any of the configured model directories"""
112 if model_name in models:
113 return models[model_name]
114
115 # Try to find the model in any of the configured directories
116 model_path = None
117 for directory in CONFIG["model_dirs"]:
118 potential_path = os.path.join(directory, model_name)
119 if os.path.exists(potential_path):
120 model_path = potential_path
121 break// Exploitable if MCP is exposed to untrusted prompts (network_exposed) or by a compromised LLM (local_only).
The model_name parameter is used to construct a file path via os.path.join without any sanitization. An attacker could use path traversal characters (e.g., '../') to load arbitrary .pt files from outside the configured directories.
ImpactAn attacker could load arbitrary .pt files from the filesystem, potentially leading to arbitrary code execution if the model file contains malicious data (e.g., pickle deserialization).
FixValidate model_name against a whitelist of allowed model names, or ensure it does not contain path traversal sequences.
386@mcp.tool()
387def track_objects(
388 image_data: str,
389 model_name: str = "yolov8n.pt",
390 confidence: float = 0.25,
391 tracker: str = "bytetrack.yaml",
392 save_results: bool = False
393) -> Dict[str, Any]:
394 ...
395 # Load model and perform tracking
396 model = get_model(model_name)
397 with redirect_stdout_to_stderr():
398 results = model.track(image, conf=confidence, tracker=tracker, save=save_results)// Exploitable if MCP is exposed to untrusted prompts (network_exposed) or by a compromised LLM (local_only).
The tracker parameter is passed directly to model.track without validation. An attacker could provide a path to an arbitrary YAML file, potentially leading to file read or other issues.
ImpactAn attacker could read arbitrary YAML files from the filesystem by providing their path as the tracker parameter.
FixRestrict tracker to a whitelist of allowed tracker names (e.g., 'bytetrack.yaml', 'botsort.yaml').
459@mcp.tool()
460def train_model(
461 dataset_path: str,
462 model_name: str = "yolov8n.pt",
463 epochs: int = 100,
464 imgsz: int = 640,
465 batch: int = 16,
466 name: str = "yolo_custom_model",
467 project: str = "runs/train"
468) -> Dict[str, Any]:
469 ...
470 with redirect_stdout_to_stderr():
471 results = model.train(
472 data=dataset_path,
473 epochs=epochs,
474 imgsz=imgsz,
475 batch=batch,
476 name=name,
477 project=project
478 )// Exploitable if MCP is exposed to untrusted prompts (network_exposed) or by a compromised LLM (local_only).
The project and name parameters are used to construct file paths for saving training results. An attacker could use path traversal to write files to arbitrary locations.
ImpactAn attacker could write files to arbitrary directories on the filesystem, potentially overwriting important files or planting malicious content.
FixRestrict project and name to safe values, or ensure they do not contain path traversal sequences.