Back to skill

Security audit

Clash VPN

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent for managing Clash, but it gives unsafe network-facing defaults and root configuration update workflows that deserve review before installation.

Install only if you are comfortable with a skill that can guide an agent to modify root-owned Clash configuration and start or stop the proxy service. Before using it, change examples to bind controller and DNS to localhost or a trusted interface, add a controller secret, back up configs, validate temporary files before replacement, and avoid exposing LAN access unless explicitly needed.

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
references/config-guide.md:13
Finding
Unauthenticated Clash Controller and DNS Service Exposed on All Network Interfaces<![CDATA[ ## Vulnerability Details **File Location**: `references/config-guide.md`, lines 13-20 **Vulnerability Type**: Insecure network service exposure and missing controller authentication **Risk Level**: High ### Vulnerable Code ```yaml allow-lan: true mode: rule log-level: info external-controller: 0.0.0.0:9090 dns: enable: true listen: 0.0.0.0:53 ``` ### Technical Analysis The recommended configuration enables LAN access and binds both the Clash external controller and DNS service to all available network interfaces. No controller authentication secret is defined in the template. Consequently, if TCP port `9090` is reachable, a remote party may interact with the Clash management API without authentication. Depending on the installed Clash implementation and enabled API functions, an attacker may inspect runtime information, alter proxy selection or configuration, and stop or disrupt the proxy service. Binding the DNS listener to `0.0.0.0:53` also exposes it beyond the local host. If network filtering does not block the port, unauthorized clients may use the host as a DNS resolver. This creates an avoidable network-facing attack surface and may permit resolver abuse. These bindings are unnecessary for the documented local use case because the Skill advertises proxy endpoints on `127.0.0.1`. ### Attack Path 1. An operator copies the recommended configuration template and starts Clash. 2. Clash binds its external controller to every network interface on TCP port `9090` and its DNS service to every interface on port `53`. 3. An attacker with network access to the host scans for or directly connects to these ports. 4. Because the template does not configure a controller secret, the attacker submits unauthenticated API requests to the Clash controller. 5. The attacker manipulates Clash runtime behavior, proxy routing, or service state within the functionality exposed by the installed Clash version. 6. Separately, unauthorized clients may send DNS ...[truncated 985 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Use local-only defaults unless remote access is explicitly required: ```yaml allow-lan: false external-controller: 127.0.0.1:9090 secret: "<strong-random-controller-secret>" dns: enable: true listen: 127.0.0.1:53 ``` Additional hardening measures: 1. Generate a strong, unique controller secret and store it with restrictive filesystem permissions. 2. Do not include a real secret directly in public documentation or source control. 3. Restrict controller and DNS ports with host and network firewall rules. 4. If LAN proxy access is required, bind only to a trusted interface and limit access to explicitly approved source networks. 5. Run Clash under a dedicated, unprivileged service account rather than as root where feasible. 6. Document that remote controller exposure requires authentication, TLS or a secure tunnel, and explicit access-control rules. 7. Add a security warning to the configuration guide explaining the consequences of `allow-lan: true` and `0.0.0.0` bindings. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/clash-vpn.sh:103
Finding
Configuration Validation Fails Open and Installs Invalid Configuration Before Verification<![CDATA[ ## Vulnerability Details **File Location**: `scripts/clash-vpn.sh`, lines 103-108 **Vulnerability Type**: Fail-open validation and unsafe configuration replacement **Risk Level**: Medium ### Vulnerable Code ```bash if "$CLASH_BIN" -t -f "$CLASH_CONFIG" 2>&1 | grep -q "Parse config error"; then echo "警告: 配置格式可能有误,请检查" else echo "配置格式验证通过" fi ``` The active configuration is written immediately before this validation: ```bash # 写入新配置 echo "$config_content" > "$CLASH_CONFIG" ``` ### Technical Analysis The script determines validation success by searching command output for the exact text `Parse config error`. It does not reliably use the Clash validator's exit status. The pipeline's status is normally the status of `grep`, not the status of the Clash command. Any validation failure that does not contain that exact English phrase is therefore reported as successful. Relevant cases include: - A different Clash error message. - A localized or version-specific diagnostic. - Semantic configuration errors. - Failure to execute the Clash binary. - A crash or abnormal validator termination. - Read or dependency failures. The script also replaces the active configuration before validation. If validation fails, it only prints a warning and neither restores the backup nor returns a failure status. The invalid or unsafe configuration consequently remains installed. ### Attack Path 1. An operator or automation passes malformed, incompatible, or attacker-influenced YAML to `scripts/clash-vpn.sh update`. 2. The script immediately overwrites `/root/.config/clash/config.yaml`. 3. Clash validation fails but emits output that does not contain the exact string `Parse config error`, or the Clash binary fails to execute. 4. `grep` finds no matching phrase, causing the script to print that validation passed. 5. Automation or the operator trusts the success message and starts or restarts Clash. 6. Clash fails to start, runs with unintended settings, or exposes ...[truncated 869 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Validate a temporary file and atomically replace the active configuration only after successful validation: ```bash config_dir=$(dirname "$CLASH_CONFIG") tmp_config=$(mktemp "$config_dir/config.yaml.tmp.XXXXXX") || return 1 chmod 600 "$tmp_config" if ! printf '%s\n' "$config_content" > "$tmp_config"; then rm -f "$tmp_config" return 1 fi if ! "$CLASH_BIN" -t -f "$tmp_config"; then echo "Configuration validation failed" rm -f "$tmp_config" return 1 fi if [ -f "$CLASH_CONFIG" ]; then cp --preserve=mode,ownership "$CLASH_CONFIG" \ "$CLASH_CONFIG.bak.$(date +%Y%m%d%H%M%S)" || { rm -f "$tmp_config" return 1 } fi mv -f "$tmp_config" "$CLASH_CONFIG" || { rm -f "$tmp_config" return 1 } echo "Configuration updated and validated" ``` Additional hardening measures: 1. Check the Clash command's exit status directly rather than parsing human-readable output. 2. Return a nonzero status for every validation failure. 3. Preserve the previous active configuration until the new one passes validation. 4. Use `printf` instead of `echo` to avoid implementation-dependent handling of input beginning with options or containing escape sequences. 5. Set restrictive permissions such as mode `0600`, because Clash configurations commonly contain proxy passwords, UUIDs, and subscription credentials. 6. Check backup and replacement operation results instead of continuing after filesystem errors. 7. Consider limiting backup retention and protecting backups with the same restrictive ownership and permissions as the active configuration. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (7)

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill clearly instructs shell-based operational actions such as starting services, validating configs, and overwriting files, but it does not declare any explicit tool scope or permission boundary. This increases the chance that an agent may execute privileged shell actions without transparent authorization controls, especially in a skill that manages network proxying and root-owned files.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill provides a direct example that overwrites /root/.config/clash/config.yaml, a root-owned system configuration file, without any warning, confirmation step, or safety guard. In context, this is more dangerous because the skill is specifically designed to accept user-supplied VPN configuration content, so malformed or malicious input could disrupt networking, reroute traffic, or replace trusted proxy settings at a privileged path.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The configuration guide recommends binding administrative and network-facing services to all interfaces via values like `external-controller: 0.0.0.0:9090` and `dns.listen: 0.0.0.0:53` without any warning, access control guidance, or restriction to trusted hosts. In the context of a VPN/proxy management skill, this is especially dangerous because it can expose a local DNS service and Clash control interface to the LAN or broader network, enabling unauthorized control, information leakage, or use of the proxy by unintended parties.

Session Persistence

Medium
Category
Rogue Agent
Content
return 1
    fi
    
    nohup "$CLASH_BIN" -f "$CLASH_CONFIG" > "$CLASH_LOG" 2>&1 &
    sleep 2
    
    if pgrep -x "clash" > /dev/null; then
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.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The script writes piped input directly to the Clash configuration file, replacing its contents. Although it creates a backup and prints a success message, there is no upfront user-facing warning or confirmation that the operation will overwrite the active config file under /root/.config/clash/config.yaml.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
The visible skill instructions and heading are written in Chinese, with no indication that the skill can respond in other languages or follow the user's preferred locale. Under the policy, language constraints should not be imposed without user opt-in or a clearly documented regional justification.

Natural-Language Policy Violations

Low
Confidence
96% confidence
Finding
All help text, status messages, and operational output are presented only in Chinese, with no option for user language selection. Under the stated policy, forcing a specific language without opt-in is a natural-language policy violation unless the locale restriction is explicitly justified.

Static analysis

No suspicious patterns detected.