Back to skill

Security audit

Mouse YOLO Factory

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly matches its image-dataset purpose, but it needs review because it can delete a dataset images folder and persist detection history to a fixed local log without clear user control.

Review this skill before installing. Run it only on copied datasets, never on the only copy of a training set, and check every base_path carefully because scratch generation can remove the images subfolder. Also expect local persistent inference history under D:/aiagent/rag_database/detection_logs.jsonl and consider clearing or relocating it if filenames or defect detections are sensitive.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
Mouse_produce_scratch.py:624
Finding
Unconditional Recursive Deletion of the Dataset Images Directory<![CDATA[ ## Vulnerability Details **File Location**: `Mouse_produce_scratch.py`, lines 624–633 **Vulnerability Type**: Destructive filesystem operation without validation or confirmation **Risk Level**: High ### Vulnerable Code ```python BASE_FOLDER = args.base_path DATA_FOLDER = BASE_FOLDER SAVE_FOLDER = BASE_FOLDER + '/images' MERGE_LABEL_FOLDER = BASE_FOLDER + '/labels' OUT_FOLDER = BASE_FOLDER + '/test' # SCRATCH_ID = args.scratch_id SCRATCH_ID = 3 LABEL_FOLDER = args.bbox_path os.makedirs(MERGE_LABEL_FOLDER, exist_ok=True) try: shutil.rmtree(SAVE_FOLDER) except: pass os.makedirs(SAVE_FOLDER, exist_ok=True) ``` ### Technical Analysis The `--base_path` command-line argument directly determines `SAVE_FOLDER`. On every invocation, the program recursively deletes the existing `<base_path>/images` directory using `shutil.rmtree()` before recreating it. The operation has no path validation, ownership check, backup, confirmation prompt, dry-run mode, or explicit overwrite option. It also uses a blanket `except` clause, which suppresses all deletion errors and prevents the user from understanding whether the filesystem operation completed safely. The deleted directory follows a conventional YOLO dataset layout and is therefore likely to contain original or valuable training images rather than disposable temporary files. This destructive behavior is not disclosed in `SKILL.md`. ### Attack Path 1. A user or automated agent is instructed to run scratch generation with a supplied `--base_path`. 2. The supplied path points to a legitimate dataset whose `images` subdirectory contains existing data. 3. `make_scratch()` constructs `SAVE_FOLDER` as `<base_path>/images`. 4. `shutil.rmtree(SAVE_FOLDER)` recursively removes that directory and its contents. 5. The program recreates an empty directory at the same location and begins writing generated output. 6. Unless an independent backup exists, the original images are irreversibly lost. An attacker does ...[truncated 891 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Never automatically delete a conventional input directory such as `<base_path>/images`. 2. Require a distinct output path, for example through a mandatory `--output_path` argument. 3. Refuse to use an existing non-empty output directory by default. 4. If replacement is necessary, require an explicit `--overwrite` flag and display the fully resolved path before deletion. 5. Resolve and validate paths with `pathlib.Path.resolve()` and reject unsafe targets such as filesystem roots, the base dataset directory itself, or paths outside an approved workspace. 6. Create a backup or use atomic directory replacement when existing output must be superseded. 7. Replace the blanket exception with specific exception handling and terminate safely when deletion fails. A safer pattern is: ```python from pathlib import Path base_folder = Path(args.base_path).resolve() output_folder = Path(args.output_path).resolve() if output_folder == base_folder or base_folder not in output_folder.parents: raise ValueError("Output directory must be a dedicated child of the dataset directory") if output_folder.exists() and any(output_folder.iterdir()): if not args.overwrite: raise FileExistsError( f"Output directory is not empty: {output_folder}. " "Use --overwrite to replace generated output." ) shutil.rmtree(output_folder) output_folder.mkdir(parents=True, exist_ok=False) ``` The destructive behavior and overwrite semantics must also be documented in `SKILL.md`. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
drawbox_and_dataset_savejson_with_model.py:55
Finding
Undisclosed Persistent Inference Logging to a Hard-Coded External Directory<![CDATA[ ## Vulnerability Details **File Location**: `drawbox_and_dataset_savejson_with_model.py`, lines 55–70 and 261–264 **Vulnerability Type**: Uncontrolled local persistence of potentially sensitive inference metadata **Risk Level**: Medium ### Vulnerable Code Logging destination and data collection, lines 55–70: ```python # --- RAG 設定 --- RAG_DB_PATH = Path("D:/aiagent/rag_database") RAG_DB_PATH.mkdir(parents=True, exist_ok=True) rag_history_file = RAG_DB_PATH / "detection_logs.jsonl" def save_to_rag_log(image_name, detections): """將偵測結果存成 JSONL,方便 RAG 讀取""" entry = { "timestamp": datetime.now().isoformat(), "source_image": image_name, "objects_detected": detections, "summary": f"In image {image_name}, detected: " + ", ".join([f"{d['label']} (conf: {d['conf']:.2f})" for d in detections]) } with open(rag_history_file, "a", encoding="utf-8") as f: f.write(json.dump_as_string(entry) if hasattr(json, 'dump_as_string') else json.dumps(entry, ensure_ascii=False) + "\n") ``` Invocation during inference, lines 261–264: ```python # --- 關鍵步驟:寫入 RAG 知識庫 --- if current_detections: save_to_rag_log(image_name, current_detections) ``` ### Technical Analysis The module creates `D:/aiagent/rag_database` at import time and appends inference records to `detection_logs.jsonl`. The records include: - Timestamps. - Source image filenames. - Detected labels. - Confidence values. - Class identifiers. - A human-readable detection summary. This logging is unconditional whenever detections are available. It is not controlled by an explicit logging option and is written outside the dataset directory selected through `--base_path`. The behavior is not clearly disclosed in the Skill documentation. Because the destination is global and hard-coded, detections from unrelated datasets or users can be mixed in one persistent file. The code does not define access controls, retention limits, rotation, ...[truncated 1916 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Make inference-history logging opt-in, disabled by default. 2. Add an explicit `--rag-log` or `--log-path` argument instead of using a hard-coded destination. 3. Store logs under the user-selected output directory unless the user explicitly chooses another location. 4. Do not create directories or files at module import time; initialize logging only inside `run_inference()` after validating configuration. 5. Document all collected fields, their purpose, destination, retention period, and deletion procedure. 6. Apply restrictive file permissions appropriate to the operating system. 7. Add log rotation, maximum size, retention, and secure deletion controls. 8. Separate logs by dataset or project to prevent cross-project contamination. 9. Permit users to exclude source filenames or replace them with non-reversible identifiers. 10. Validate and resolve the configured log path before use. A safer design is: ```python def save_to_rag_log(log_path, image_name, detections): entry = { "timestamp": datetime.now().isoformat(), "source_image": image_name, "objects_detected": detections, } log_path = Path(log_path).resolve() log_path.parent.mkdir(parents=True, exist_ok=True) with log_path.open("a", encoding="utf-8") as f: f.write(json.dumps(entry, ensure_ascii=False) + "\n") # Logging remains disabled unless the user explicitly supplies --rag-log. if args.rag_log and current_detections: save_to_rag_log(args.rag_log, image_name, current_detections) ``` Where possible, create the file with permissions that restrict access to the invoking user and provide a documented command for purging retained inference history. ]]>
Vulnerability Patterns
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (9)

Missing User Warnings

Medium
Confidence
83% confidence
Finding
This code creates a new dataset version directory structure and later copies many image and label files into it, which is a safety-relevant file-write operation. Although there are progress log messages, there is no explicit warning, confirmation, or comment/docstring disclosure that running this method will materialize a new dataset tree and write a merge log to disk.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script unconditionally calls shutil.rmtree on SAVE_FOLDER, which is derived from a user-controlled --base_path, and suppresses all exceptions. In an agent or automated pipeline context, a wrong or manipulated base path could cause destructive deletion of unintended directories without warning, making this a genuine integrity risk.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The inline CLI documentation labels this tool as a 'YOLO RAG Processor', which implies retrieval/processing functionality unrelated to image augmentation. The implemented behavior in make_scratch instead modifies images, creates scratch annotations, merges labels, and saves visualization outputs, so the documentation actively misstates the tool's intent.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The natural-language instructions and usage guidance are entirely presented in Traditional Chinese, which can force a specific language on users without opt-in. The file does not indicate that the skill is region-specific or offer an alternative language, so it may violate a language/locale policy requiring user choice or justification.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The code persists structured detection metadata from user-supplied images into a long-lived JSONL 'RAG database' at a fixed path with no opt-in, minimization, or access control. Even if only labels and confidences are stored, the image name, timestamp, and detection summary can leak sensitive operational context and create an unexpected secondary data store that broadens privacy and compliance risk.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The script automatically creates output directories and writes copied/derived image artifacts plus labels without any explicit notice, consent flow, or retention control. In image-processing workflows, silent persistence can expose sensitive visual data, filesystem locations, and derived annotations to later users or processes, especially on shared machines or regulated datasets.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
The comment at L260 says the code is collecting structured information for RAG, but the appended object uses `label` from the earlier per-box loop rather than deriving the label from `cls_id` for the current NMS-retained detection. This means the saved RAG log can misstate which object classes were detected, diverging from the code comment's stated intent of accurately recording detection results.

Natural-Language Policy Violations

Low
Confidence
76% confidence
Finding
The natural-language docstring and user-facing log/comment text are written only in Traditional Chinese, which can amount to a language/locale constraint if this skill is intended for general use. There is no visible indication that the user can choose another language or that the locale restriction is intentional and documented.

Missing User Warnings

Low
Confidence
83% confidence
Finding
When backup is enabled, the code renames the original label file to .bak and then rewrites the original path, which can overwrite prior backups or modified outputs without confirmation. In batch processing, this can silently destroy provenance and previous data, especially if rerun multiple times on the same dataset.

Static analysis

No suspicious patterns detected.