Back to skill

Security audit

MLX Local AI

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly matches a local AI setup, but it has under-disclosed high-impact behaviors that should be reviewed before installation.

Review this skill carefully before installing. It may run local background AI services, modify shell startup configuration, install unpinned dependencies, download model artifacts from a third-party mirror, execute model-supplied code, and route OpenClaw requests to a remote Baidu provider unless the configuration is changed.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T03 · Remote Payload Retrieval and Execution

Error
Location
start_ai.sh:38
Finding
Mutable Model Payload Is Executed with Remote Code Trust Enabled<![CDATA[ ## Vulnerability Details **File Location**: `install.sh:20, 130-147`; `start_ai.sh:6, 38-46`; `SKILL.md:122-123` **Vulnerability Type**: Remote payload retrieval and execution **Risk Level**: Critical ### Vulnerable Code `install.sh:20`: ```bash HF_MIRROR="https://hf-mirror.com" ``` `install.sh:130-147`: ```bash download_models() { log_info "下载模型 (这可能需要几分钟)..." source "$VENV_DIR/bin/activate" export HF_ENDPOINT="$HF_MIRROR" # 下载 LLM 模型 log_info "下载 LLM 模型: $MODEL_NAME" python3 -c "from mlx_lm import load; load('$MODEL_NAME')" || { log_warning "LLM 模型下载可能已存在或失败,继续..." } # 下载 Embedding 模型 log_info "下载 Embedding 模型: $EMBEDDING_MODEL" python3 -c "from sentence_transformers import SentenceTransformer; SentenceTransformer('$EMBEDDING_MODEL')" || { log_warning "Embedding 模型下载可能已存在或失败,继续..." } ``` `start_ai.sh:6, 38-46`: ```bash export HF_ENDPOINT=https://hf-mirror.com ``` ```bash nohup python -m mlx_lm.server \ --model mlx-community/Qwen3.5-4B-OptiQ-4bit \ --trust-remote-code \ --temp 0.3 \ --chat-template-args '{"enable_thinking": false}' \ --port 8080 > "$LOG_DIR/chat.log" 2>&1 & ``` `SKILL.md:122-123`: ```bash source ~/mlx-env/bin/activate HF_ENDPOINT=https://hf-mirror.com python3 -c "from mlx_lm import load; load('mlx-community/Qwen3.5-4B-OptiQ-4bit')" ``` ### Technical Analysis The installer retrieves model artifacts through `hf-mirror.com`, a third-party mirror, without pinning an immutable repository revision or validating cryptographic hashes or signatures. The launcher subsequently passes `--trust-remote-code` to the model server. Remote-code trust allows custom implementation code supplied by a model repository to be imported and executed locally. Because the model reference is mutable and no integrity control is enforced, the effective executable payload can change after the Skill package has been reviewed. The local scripts can therefore app ...[truncated 1160 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `--trust-remote-code` unless the selected model strictly requires custom executable code. 2. Prefer a model format and loader that operate entirely on declarative model artifacts. 3. Retrieve artifacts from an official, authenticated source rather than an undocumented third-party mirror. 4. Pin the model to a reviewed immutable commit or revision instead of a mutable repository name. 5. Publish and validate cryptographic hashes or signed manifests before loading downloaded files. 6. If remote model code is unavoidable, vendor the reviewed code into the package, audit it, and execute it in a sandbox with minimal filesystem and network access. 7. Require explicit user confirmation explaining that model-supplied code will execute locally. 8. Fail closed when model verification or download fails rather than continuing after a warning. ]]>

T08 · Insecure Dependencies

Error
Location
install.sh:110
Finding
Installer Executes Unpinned Python Dependencies<![CDATA[ ## Vulnerability Details **File Location**: `install.sh:110-125` **Vulnerability Type**: Uncontrolled third-party dependency installation **Risk Level**: High ### Vulnerable Code ```bash install_dependencies() { log_info "安装 Python 依赖..." source "$VENV_DIR/bin/activate" # 升级 pip pip install --upgrade pip # 安装 MLX 和 MLX-LM log_info "安装 MLX 和 MLX-LM..." pip install mlx mlx-lm # 安装 sentence-transformers (用于 Embedding) log_info "安装 sentence-transformers..." pip install sentence-transformers # 安装其他依赖 pip install flask requests numpy ``` ### Technical Analysis The installer upgrades `pip` and installs several packages by name without exact version pins, artifact hashes, a reviewed lockfile, or an explicit trusted package index. Pip also resolves and installs mutable transitive dependencies. Consequently, the code executed by a fresh installation is not determined solely by the audited project. A compromised package release, package-index account, dependency, or resolver result could introduce malicious installation or runtime code. Re-running the documented update mode can also retrieve different package versions without any change to this repository. ### Attack Path 1. An attacker compromises a named package, one of its transitive dependencies, or the package distribution account/index. 2. A malicious or backdoored release becomes eligible for normal dependency resolution. 3. A user runs `install.sh` or `install.sh --update`. 4. Pip resolves and installs the attacker-controlled release because no version or hash restriction rejects it. 5. Malicious package code executes during installation, import, or subsequent service startup with the user's privileges. ### Impact Assessment Exploitation can result in arbitrary code execution as the installing user. An attacker could access user-readable files, tokens and environment variables, tamper with the virtual environment or installe ...[truncated 238 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a reviewed dependency lockfile containing exact versions for direct and transitive dependencies. 2. Require artifact hashes during installation, for example with pip's `--require-hashes` option. 3. Use an explicitly configured, authenticated package index and prevent unexpected fallback indexes. 4. Do not upgrade `pip` implicitly as part of normal installation; pin and verify the required installer version. 5. Separate development dependencies from the minimum runtime dependency set. 6. Add a controlled update process that reviews release notes, dependency changes, and artifact provenance before modifying the lockfile. 7. Consider generating a software bill of materials and scanning locked artifacts for known vulnerabilities. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
start_ai.sh:55
Finding
Service Stop Operation Can Terminate Unrelated User Processes<![CDATA[ ## Vulnerability Details **File Location**: `start_ai.sh:55-71` **Vulnerability Type**: Overbroad process matching and termination **Risk Level**: Medium ### Vulnerable Code ```bash stop_services() { echo "🛑 停止 AI 服务..." # 停止 Chat 服务 if pgrep -f "mlx_lm.server" > /dev/null; then pkill -f "mlx_lm.server" echo "✅ Chat 服务已停止" else echo "ℹ️ Chat 服务未运行" fi # 停止 Embedding 服务 if pgrep -f "embedding_server.py" > /dev/null; then pkill -f "embedding_server.py" echo "✅ Embedding 服务已停止" else echo "ℹ️ Embedding 服务未运行" fi } ``` ### Technical Analysis `pgrep -f` and `pkill -f` match text anywhere in the complete command line. The launcher does not record the process identifiers of the child processes it starts and does not verify that a matched process belongs to this installation. Any same-user process whose command line contains `mlx_lm.server` or `embedding_server.py` can therefore be selected. The stop and restart operations may terminate other projects, test processes, or unrelated services that happen to use the same module or filename. ### Attack Path 1. Another user-owned process runs with either matching string in its command line. 2. The user invokes `start_ai.sh stop`, `start_ai.sh restart`, or the uninstaller, which calls the stop action. 3. `pkill -f` selects every accessible matching process rather than only the instances created by this Skill. 4. The unrelated process receives a termination signal and stops. ### Impact Assessment The immediate impact is denial of service against unrelated processes owned by the same user. Depending on the affected application, abrupt termination could interrupt active work, corrupt partially written state, or cause loss of unsaved data. The code does not demonstrate the ability to terminate processes belonging to other users without additional privileges. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Capture each background process ID immediately after startup using `$!`. 2. Store process IDs in separate PID files inside a user-owned directory with restrictive permissions. 3. Before signaling a stored PID, verify that it still belongs to the current user and that its executable and expected arguments match the launched service. 4. Send `TERM` only to the verified PID, wait for graceful shutdown, and use `KILL` only as a documented last resort. 5. Remove stale PID files safely and avoid using global command-line substring matching for lifecycle management. 6. Consider using a dedicated macOS LaunchAgent with explicit labels if managed background execution is required. ]]>

other

Warning
Location
config/openclaw.json:27
Finding
Local AI Configuration Selects a Remote Provider as the Primary Model<![CDATA[ ## Vulnerability Details **File Location**: `config/openclaw.json:27-34` **Vulnerability Type**: Unintended external data routing **Risk Level**: Medium ### Vulnerable Code ```json "agents": { "defaults": { "model": { "primary": "baiduqianfancodingplan/qianfan-code-latest", "fallbacks": [ "mlx-local/mlx-community/Qwen3.5-4B-OptiQ-4bit" ] }, ``` ### Technical Analysis The project is presented as a local AI deployment, but the supplied OpenClaw configuration selects `baiduqianfancodingplan/qianfan-code-latest` as the primary model. The local MLX model is only configured as a fallback. If this configuration is applied in an environment where the named remote provider is available, normal requests can be routed to the external provider before the local model is considered. This conflicts with the reasonable expectation that prompts submitted through a local AI configuration remain on the device. The package does not clearly disclose or require consent for this default external routing. ### Attack Path 1. The user installs the Skill and applies `config/openclaw.json` to an OpenClaw environment configured for the named Baidu provider. 2. The user submits a prompt believing the advertised local AI service will process it. 3. OpenClaw selects the configured remote primary model. 4. Prompt content and associated request metadata are transmitted to the external provider. 5. The local model is used only if fallback behavior is triggered. ### Impact Assessment Potentially sensitive prompts, source code, business information, or personal data may leave the local system and enter an external provider's processing environment. The exact external retention and downstream access depend on the separately configured provider and its policies. This finding does not establish credential theft or guaranteed transmission in every deployment because the remote provider must also be available and configured. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Set `mlx-local/mlx-community/Qwen3.5-4B-OptiQ-4bit` as the primary model. 2. Remove the remote provider from the default configuration unless remote processing is essential to the Skill. 3. Make any external fallback explicitly opt-in and explain what data may leave the device. 4. Display a clear confirmation before enabling remote routing. 5. Document provider privacy, retention, and authentication requirements. 6. Add a local-only configuration mode that rejects remote providers rather than silently falling back to them. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (24)

Ae1

High
Category
analysis-evasion
Content
./uninstall.sh
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Tool Parameter Abuse

High
Category
Tool Misuse
Content
log_info "卸载..."
        rm -rf "$VENV_DIR"
        rm -f "$HOME/start_ai.sh"
        rm -f "$HOME/embedding_server.py"
        log_success "卸载完成"
        ;;
    *)
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
rm -rf "$VENV_DIR"

echo -e "${YELLOW}删除启动脚本...${NC}"
rm -f "$HOME/start_ai.sh"

echo -e "${YELLOW}删除日志文件...${NC}"
rm -rf "$LOG_DIR"
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
rm -rf "$VENV_DIR"

echo -e "${YELLOW}删除启动脚本...${NC}"
rm -f "$HOME/start_ai.sh"

echo -e "${YELLOW}删除日志文件...${NC}"
rm -rf "$LOG_DIR"
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
echo -e "${GREEN}✅ 卸载完成${NC}"
echo ""
echo "注意: 模型缓存未删除,如需删除请运行:"
echo "  rm -rf ~/.cache/huggingface/hub/models--mlx-community--Qwen3.5-4B-OptiQ-4bit"
echo "  rm -rf ~/.cache/huggingface/hub/models--BAAI--bge-base-zh-v1.5"
Confidence
100% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
echo -e "${GREEN}✅ 卸载完成${NC}"
echo ""
echo "注意: 模型缓存未删除,如需删除请运行:"
echo "  rm -rf ~/.cache/huggingface/hub/models--mlx-community--Qwen3.5-4B-OptiQ-4bit"
echo "  rm -rf ~/.cache/huggingface/hub/models--BAAI--bge-base-zh-v1.5"
Confidence
100% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
echo -e "${GREEN}✅ 卸载完成${NC}"
echo ""
echo "注意: 模型缓存未删除,如需删除请运行:"
echo "  rm -rf ~/.cache/huggingface/hub/models--mlx-community--Qwen3.5-4B-OptiQ-4bit"
echo "  rm -rf ~/.cache/huggingface/hub/models--BAAI--bge-base-zh-v1.5"
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
echo -e "${GREEN}✅ 卸载完成${NC}"
echo ""
echo "注意: 模型缓存未删除,如需删除请运行:"
echo "  rm -rf ~/.cache/huggingface/hub/models--mlx-community--Qwen3.5-4B-OptiQ-4bit"
echo "  rm -rf ~/.cache/huggingface/hub/models--BAAI--bge-base-zh-v1.5"
Confidence
100% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
echo ""
echo "注意: 模型缓存未删除,如需删除请运行:"
echo "  rm -rf ~/.cache/huggingface/hub/models--mlx-community--Qwen3.5-4B-OptiQ-4bit"
echo "  rm -rf ~/.cache/huggingface/hub/models--BAAI--bge-base-zh-v1.5"
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Missing User Warnings

Medium
Confidence
89% confidence
Finding
This markdown file instructs users to run installation and service-management commands, and the file structure explicitly includes an uninstall script, but the README does not warn that these actions may modify the local system and start network-accessible services on ports 8080 and 8081. For markdown files, omission of warnings about behaviors affecting user data, privacy, or system integrity is in scope for SQP-2.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The file presents all user-facing instructions in Chinese, including setup and operational steps, with no indication that the user can choose another language. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation unless the locale restriction is clearly justified.

External Transmission

Medium
Category
Data Exfiltration
Content
### Chat API

```bash
curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mlx-community/Qwen3.5-4B-OptiQ-4bit",
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The documentation tells users to copy environment settings into shell startup files and append a source command to ~/.zshrc, creating a persistent system-wide change for that user session without any warning or rollback guidance. Persistent shell initialization changes can unintentionally alter future terminal behavior, expose secrets if sensitive variables are included, or make later troubleshooting difficult.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script automatically performs remote network actions by installing Python packages from package indexes and downloading models from a Hugging Face mirror, but it does not clearly warn the user that external downloads will occur or what hosts will be contacted. This increases supply-chain and privacy risk because users may unknowingly execute code and retrieve artifacts from third-party infrastructure during installation.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The uninstall path deletes files and a virtual environment under the user's home directory without any confirmation prompt, dry-run, or explicit destructive-action warning. Even though the paths are fixed and quoted, accidental invocation can still cause unintended data loss or removal of locally modified files.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Content
def check_package(package_name):
    """检查 Python 包是否安装"""
    try:
        __import__(package_name)
        print(f"✓ {package_name} 已安装")
        return True
    except ImportError:
Confidence
75% confidence
Finding
Dynamic __import__() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This code uses Chinese-only natural-language descriptions, prompts, and status messages, including the test input sent to the API and all user-facing output. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly documented and justified, which is not present here.

Session Persistence

Medium
Category
Rogue Agent
Content
echo "✅ Embedding 服务已运行 (端口 8081)"
    else
        echo "📊 启动 Embedding 服务..."
        nohup python ~/embedding_server.py > "$LOG_DIR/embedding.log" 2>&1 &
        sleep 3
        if check_embedding; then
            echo "✅ Embedding 服务启动成功"
Confidence
65% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
echo "✅ Chat 服务已运行 (端口 8080)"
    else
        echo "💬 启动 Chat 服务 (mlx-community/Qwen3.5-4B-OptiQ-4bit)..."
        nohup python -m mlx_lm.server \
            --model mlx-community/Qwen3.5-4B-OptiQ-4bit \
            --trust-remote-code \
            --temp 0.3 \
Confidence
93% confidence
Finding
The chat service is launched with --trust-remote-code, which permits execution of model-supplied code during model loading. In this script, the model is fetched via a mirror endpoint, so a compromised or untrusted upstream source could cause arbitrary code execution under the user account when the service starts.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The script's user-facing title, confirmation prompt, status messages, and completion notice are all written in Chinese. This creates a natural-language locale policy concern because users are not given any language/locale choice, and the file does not indicate that the skill is intentionally limited to a Chinese-speaking or region-specific audience.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The README presents all operational instructions in Chinese, including setup and publishing steps, with no indication that users may choose another language or that the skill is intentionally limited to a Chinese-speaking or region-specific audience. The policy requires flagging language or locale constraints when they are imposed without opt-in or clear justification.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
All prompts, status messages, and instructions are presented in Chinese, which effectively forces a single language for interaction. The policy allows locale constraints only when users are given a choice or when the restriction is clearly documented and justified, which is not present here.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
This code file contains natural-language strings entirely in Chinese, beginning with the module description, and all subsequent user-facing print messages follow the same locale choice. Under the policy rule, forcing a specific language without user opt-in is a natural-language policy violation because users are not given any locale selection or fallback.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The script's natural-language comments and all user-facing echo messages are in Chinese, and there is no indication that the skill is region-specific or that users can opt into another language. This can violate a language/locale policy that requires user choice or documented justification for a fixed locale.

Static analysis

No suspicious patterns detected.