Back to skill

Security audit

Auto Model Selector

Security checks for vulnerabilities and agentic risk

Overview

This model-routing skill is coherent in purpose, but it needs review because it automatically contacts a hard-coded private-network Ollama server over plaintext HTTP, can send full prompts there, and can rewrite model configuration without clear user consent.

Install only if you control and trust the Ollama service at 192.168.10.14 and are comfortable with prompts being sent to it over plaintext HTTP. Prefer changing the endpoint to localhost or a secured, explicitly configured server before use, and review the automatic model-detection behavior because it can rewrite the skill's model configuration during normal imports or routing.

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
smart_router.py:124
Finding
Full User Prompts Transmitted over Plaintext HTTP to a Hard-Coded LAN Host<![CDATA[ ## Vulnerability Details **File Location**: `smart_router.py:28`, `smart_router.py:124-145` **Vulnerability Type**: Plaintext transmission of potentially sensitive user data **Risk Level**: High ### Vulnerable Code ```python class SmartRouter: def __init__(self, ollama_host: str = "http://192.168.10.14:11434"): self.ollama_host = ollama_host self.judge_model = "deepseek-r1:1.5b" ``` ```python response = requests.post( f"{self.ollama_host}/api/generate", json={ "model": self.judge_model, "prompt": f"""请判断以下用户请求是简单请求还是复杂请求: 用户请求:{prompt} 简单请求通常包括:问候、简单查询、文件操作、提醒设置、简短回答等。 复杂请求通常包括:代码编写、复杂分析、创意写作、详细解释、逻辑推理等。 请只回答一个字:"简单" 或 "复杂",不要其他任何内容。""", "stream": False, "options": { "temperature": 0.1, "max_tokens": 10 } }, timeout=5 ) ``` ### Technical Analysis When regex-based classification cannot determine the complexity of a request, `judge_with_model()` embeds the complete user prompt in a JSON request and sends it to the fixed address `192.168.10.14:11434`. The connection uses unauthenticated plaintext HTTP. It therefore provides neither transport confidentiality nor server identity verification. User prompts can contain credentials, source code, personal information, internal file contents, or confidential operational instructions. Such content can be observed by an attacker with access to the local network path or received by an unauthorized service controlling the configured IP address. Using a model to classify ambiguous prompts is consistent with the declared routing functionality. However, forwarding the complete raw prompt to a hard-coded network host without consent, redaction, authentication, or a secure transport exceeds the minimum privileges necessary for classification. The Skill documentation mentions an Ollama service but does not clearly warn that complete prompts may be transmitted to this fixed LAN host. ### Attack Path 1. A user su ...[truncated 1098 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Default the Ollama endpoint to a loopback address such as `http://127.0.0.1:11434`, not a developer-specific LAN address. 2. Require the endpoint to be explicitly configured by the user through a configuration file or environment variable. 3. Do not transmit prompts until the user has been clearly informed of, and has consented to, the data flow. 4. Use HTTPS with certificate verification and authenticated access whenever the endpoint is not strictly local. 5. Provide an enforced offline mode that only uses deterministic local classification. 6. Prefer sending derived features, such as prompt length and locally detected categories, rather than the complete prompt. 7. Detect and redact likely credentials, tokens, private keys, and other sensitive values before any model request. 8. Reject non-loopback plaintext endpoints by default and require an explicit security override for trusted private networks. 9. Document the exact recipient, transmitted fields, retention assumptions, and conditions under which prompt transmission occurs. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
smart_router.py:35
Finding
Module Import Triggers Unauthenticated Network Discovery and Persistent Configuration Changes<![CDATA[ ## Vulnerability Details **File Location**: `smart_router.py:35-37`, `smart_router.py:266`; `model_manager.py:74-84`, `model_manager.py:129-150` **Vulnerability Type**: Unsafe import-time side effects and unauthenticated configuration discovery **Risk Level**: Medium ### Vulnerable Code ```python if MODEL_MANAGER_AVAILABLE: model_manager.update_config_from_detection() print("[智能路由] 模型管理器已初始化") ``` ```python router = SmartRouter() ``` The initialization invokes this network discovery code: ```python result = subprocess.run( ["curl", "-s", "http://192.168.10.14:11434/api/tags"], capture_output=True, text=True, timeout=5 ) ``` The discovered data is then incorporated into persistent configuration: ```python def update_config_from_detection(self) -> None: """根据检测结果更新配置""" detected_models = self.detect_available_models() # 更新或添加新检测到的模型 for model_id, detected_config in detected_models.items(): if model_id not in self.models: # 新模型,添加到配置 self.models[model_id] = detected_config print(f"[模型管理器] 添加新模型: {model_id}") else: # 更新现有模型的enable状态 if detected_config.get("detected", False): self.models[model_id]["enable"] = True else: self.models[model_id]["enable"] = False # 标记未检测到的模型为禁用 for model_id in list(self.models.keys()): if model_id not in detected_models: self.models[model_id]["enable"] = False self.save_config() ``` ### Technical Analysis The module-level singleton `router = SmartRouter()` causes the constructor to run whenever `smart_router` is imported. The constructor immediately calls `model_manager.update_config_from_detection()`. This operation: 1. Executes the external `curl` binary. 2. Contacts a hard-coded LAN address over unauthenticated HTTP. 3. Parses model names returned by that service. 4. Adds those model names to in-memory configur ...[truncated 2204 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove network discovery and file writes from `SmartRouter.__init__()` and all module-level initialization. 2. Make discovery an explicit administrative action, such as the existing `detect` or `update` command. 3. Separate read-only router initialization from configuration management. 4. Obtain user confirmation before persisting discovered models or disabling existing entries. 5. Use the same user-configured endpoint throughout the project instead of duplicating a hard-coded address. 6. Use an authenticated HTTPS client with certificate validation for any non-loopback service. 7. Replace the external `curl` dependency with a controlled HTTP library call and enforce response-size limits. 8. Strictly validate response structure, model-name length, allowed characters, entry count, and expected field types. 9. Write configuration atomically through a temporary file followed by a rename, and preserve a recoverable backup. 10. Do not disable existing models merely because a transient network discovery request omitted them. 11. Ensure normal imports are deterministic, offline, and free from persistent filesystem side effects. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (16)

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The README explicitly instructs users to configure a non-local Ollama host using an HTTP URL on a LAN IP address, but it does not warn that user prompts may be transmitted off-host to that service. Because the skill routes requests based on prompt content and may invoke a model for classification, sensitive user input could be sent over the network without informed user consent, creating privacy and data-handling risk even if the remote host is operator-controlled.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill explicitly states that complex requests will be handled by a cloud model/API, but it does not warn users that their prompts and potentially sensitive contents may be transmitted off-device. This creates a privacy and data-handling risk because users may unknowingly send proprietary code, credentials, file contents, or other sensitive material to a third-party service.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill describes automatic per-request model switching based on task complexity, while listing file operations and command-related tasks among routed behaviors, but it does not define safeguards preventing sensitive operational context from being sent to the cloud. Automatic routing increases the chance that users will not realize when task details, filenames, command text, or related context are transmitted to a remote model.

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
The file’s natural-language descriptions and user-facing CLI messages are entirely in Chinese, with no indication that language is selectable or limited to a region-specific deployment. This creates a locale policy concern because the skill effectively forces one language without user choice or justification.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The `update_models` path invokes `model_manager.update_config_from_detection()`, which appears to change model configuration state, but the code provides no confirmation prompt and no user-facing warning that this command may rewrite or alter configuration. The docstring only says it updates configuration, which is not a clear safety disclosure for a state-changing operation.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The `remove_model` function deletes a model entry via `model_manager.remove_model(model_id)` and the CLI executes it immediately after receiving an ID. Although success/failure is printed afterward, there is no prior warning, confirmation, or explanatory comment/documentation alerting the user that this is a destructive action.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This Python file contains natural-language descriptions and CLI output exclusively in Chinese, beginning with the module docstring and continuing throughout the command help and status messages. Because the file does not offer user opt-in for language selection or justify a Chinese-only locale restriction, it can violate language/locale policy requirements.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The module title, docstrings, and all user-facing messages are written exclusively in Chinese, which imposes a specific language on users without offering a choice. The stated purpose is generic model management rather than a clearly region-specific or compliance-bound workflow, so the locale constraint is not justified in the file.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The function claims to detect local Ollama models, but actually queries a fixed remote host at 192.168.10.14. This mismatch is security-relevant because operators may believe the code is only inspecting local state when it is actually performing network access to another machine, which can expose internal network details and trust remote-controlled data as if it were local.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
try:
            # 尝试获取Ollama模型列表
            result = subprocess.run(
                ["curl", "-s", "http://192.168.10.14:11434/api/tags"],
                capture_output=True,
                text=True,
Confidence
90% confidence
Finding
The code invokes an external program to make a network request to a hard-coded private IP address, which creates an unexpected trust boundary and allows the skill to contact a remote service during model discovery. While there is no shell injection here because arguments are passed as a list, the subprocess plus hidden remote dependency can leak environment/network metadata, bypass expected local-only behavior, and make execution depend on an untrusted host.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
This manifest uses Chinese-only natural-language labels and descriptions for the configured models, such as task routing notes in parentheses and Chinese descriptions. Under the policy provided, forcing a specific language or locale without opt-in or documented justification is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
84% confidence
Finding
Docstrings, status messages, prompts, and routing instructions are written exclusively in Chinese, which implies a fixed language/locale experience. The file does not indicate that users can opt into another language or that the locale restriction is documented and justified.

External Transmission

Medium
Category
Data Exfiltration
Content
if cache_key in self.cache:
                return self.cache[cache_key]
            
            response = requests.post(
                f"{self.ollama_host}/api/generate",
                json={
                    "model": self.judge_model,
Confidence
97% confidence
Finding
The code performs an external POST request containing raw user prompt content to a model endpoint. This is dangerous because prompt text can contain secrets, personal data, or proprietary content, and transmission over unsecured HTTP to a configurable host increases exposure to interception, unauthorized collection, or misuse by the receiving service.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The router sends the full user prompt to an HTTP network service for classification without any disclosure, consent flow, or minimization. Because prompts may contain sensitive user data and the default host is a private-network endpoint over plain HTTP, this creates a real privacy and data-exposure risk if the service is untrusted, intercepted, or logs requests.

Natural-Language Policy Violations

Low
Confidence
92% confidence
Finding
The natural-language description and usage instructions are entirely in Chinese, and the file does not indicate that the skill is region-specific or provide an opt-in language choice. Under the stated policy, forcing a specific language without user choice is a locale-policy concern.

Natural-Language Policy Violations

Low
Confidence
96% confidence
Finding
This code includes user-facing comments and error output in Chinese only, such as the error messages at L09 and L15. The file provides no language choice, opt-in, or justification for enforcing a Chinese locale, which conflicts with the policy against forcing a specific language without user choice.

Static analysis

No suspicious patterns detected.