Back to skill

Security audit

Alibaba Cloud Model Setup

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real OpenClaw Alibaba Cloud setup helper, but documented safe modes do not match the script and can still expose credentials or change configuration unexpectedly.

Review before installing. Use it only if you are comfortable with a local script editing your OpenClaw config and changing default models. Avoid passing API keys with --api-key, avoid inline storage, and do not rely on --list-models or env-var mode until those implementation mismatches are fixed. Use a scoped/rotatable Alibaba Cloud key and check config and backup file permissions afterward.

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 (4)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/alibaba_cloud_model_setup.py:394
Finding
Inline API keys are stored without enforcing restrictive file permissions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/alibaba_cloud_model_setup.py:394-408` and `scripts/alibaba_cloud_model_setup.py:447-448` **Vulnerability Type**: Plaintext credential storage with insufficient permission enforcement **Risk Level**: Medium ### Vulnerable Code ```python def save_config(config_path: Path, config: Dict[str, Any]) -> None: """Save config to JSON file with pretty formatting.""" config_path.parent.mkdir(parents=True, exist_ok=True) with open(config_path, "w", encoding="utf-8") as f: json.dump(config, f, indent=2, ensure_ascii=False) f.write("\n") ``` ```python if api_key_source == "inline": provider_config["apiKey"] = api_key # else: apiKey will be read from env var ``` ### Technical Analysis When inline storage is selected, the script inserts the plaintext Alibaba Cloud API key into the OpenClaw JSON configuration. The file is opened using the process's default permission behavior, and the script neither creates it with an explicit owner-only mode nor corrects permissions on an existing file. The resulting permissions depend on the current umask. On systems with permissive defaults, a newly created configuration may be readable by other local users. An existing configuration with weak permissions also remains weak. Timestamped backups can preserve the same sensitive content and inherited permissions. The network transmission of the API key to a fixed Alibaba Cloud HTTPS endpoint is consistent with the declared validation functionality. The vulnerability is the subsequent plaintext storage without enforced filesystem protection. ### Attack Path 1. A user runs the configurator and selects `inline` API-key storage. 2. The script adds the API key to `models.providers.bailian.apiKey`. 3. The script creates or rewrites the configuration without enforcing mode `0600`. 4. The file or a generated backup remains readable under local filesystem permissions. 5. Another local account or comprom ...[truncated 631 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prefer a supported environment-variable or secret-manager reference instead of embedding the key in JSON. 2. Create new sensitive files atomically with owner-only permissions, such as mode `0600`. 3. Explicitly apply `chmod(0o600)` after replacing an existing configuration and each backup. 4. Verify that the parent directory is not writable or traversable by unauthorized users. 5. Warn users immediately before inline storage and require explicit confirmation. 6. Consider preventing plaintext backup creation when the configuration contains credentials, or secure every backup identically. 7. Add automated tests that assert restrictive permissions for newly created files, existing files, and backups. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/alibaba_cloud_model_setup.py:106
Finding
API keys can be exposed through command-line arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/alibaba_cloud_model_setup.py:106` and `scripts/alibaba_cloud_model_setup.py:498-500` **Vulnerability Type**: Sensitive information exposure through process arguments **Risk Level**: Medium ### Vulnerable Code ```python parser.add_argument("--api-key", help="DashScope API key.") ``` ```python api_key = args.api_key if not api_key: api_key = prompt_api_key() ``` ### Technical Analysis The `--api-key` option permits a live cloud credential to be supplied directly in the command line. Depending on the operating system and execution environment, process arguments may be visible through process inspection utilities, job-control systems, audit records, automation logs, terminal history, or shell history. The interactive fallback uses `getpass`, which avoids terminal echo and is safer. However, the existence and documented usability of the command-line option allow users and automation systems to bypass that protection. ### Attack Path 1. A user or automation process invokes the script with `--api-key <secret>`. 2. The complete command is stored in shell history, CI output, orchestration metadata, or process accounting, or is temporarily exposed in the process list. 3. Another local user or a party with access to those logs retrieves the argument. 4. The attacker reuses the API key against the corresponding Alibaba Cloud endpoint. ### Impact Assessment An attacker can obtain all cloud privileges associated with the exposed API key. Likely consequences include unauthorized model requests, quota or billing consumption, and access to any other API operations permitted to the credential. The issue does not independently elevate local operating-system privileges. Exploitation requires visibility into process arguments, history, or execution logs. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the `--api-key` command-line option. 2. Accept credentials through the hidden interactive prompt, protected standard input, an inherited environment variable, or a supported secret manager. 3. If non-interactive execution is required, accept a file descriptor or path to an owner-readable secret file rather than the secret value itself. 4. If backward compatibility requires retaining the option, mark it as unsafe, display a prominent warning, and exclude it from examples. 5. Ensure operational logs and exception messages never include parsed argument values. 6. Document credential rotation procedures for users who previously supplied keys on the command line. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/alibaba_cloud_model_setup.py:146
Finding
Documented list-only mode unexpectedly validates credentials and writes configuration<![CDATA[ ## Vulnerability Details **File Location**: `scripts/alibaba_cloud_model_setup.py:146-151` and `scripts/alibaba_cloud_model_setup.py:498-540`; documentation at `SKILL.md:97-103` **Vulnerability Type**: Unexpected state-changing behavior and violation of least surprise **Risk Level**: Medium ### Vulnerable Code ```python parser.add_argument( "--list-models", action="store_true", help="List available models for the selected site and exit.", ) ``` The main workflow does not inspect `args.list_models` before collecting and transmitting the key or writing the configuration: ```python api_key = args.api_key if not api_key: api_key = prompt_api_key() print("\n🔑 Validating API key...") if not validate_api_key(base_url, api_key): print("❌ API key validation failed. Exiting.") return 1 api_key_source = args.api_key_source or prompt_api_key_source() env_var = args.env_var or "DASHSCOPE_API_KEY" if config_path.exists(): backup_config(config_path) config = load_config(config_path) update_config( config, base_url, api_key, api_key_source, env_var, models, primary_model, set_default, ) save_config(config_path, config) ``` The documentation describes the same operation as read-only: ```bash # List available models (no config write): python3 scripts/alibaba_cloud_model_setup.py \ --plan-type coding \ --site cn \ --list-models \ --non-interactive ``` ### Technical Analysis The parser promises that `--list-models` will list models and exit, while the Skill documentation explicitly states that the operation performs no configuration write. The implementation never branches on this option. Consequently, a user invoking the documented read-only command enters the ordinary configuration workflow. That workflow requests and transmits an API key for validation, creates a backup, modifies the provider configuration, and saves it. It may also alter the default model depending on the selected optio ...[truncated 1100 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Handle `args.list_models` immediately after resolving the plan and site. 2. Print the applicable static model list and return before requesting a credential, reading configuration, creating a backup, or writing files. 3. If the intended behavior is to fetch a live model list, state that network access and credential transmission are required, invoke `list_live_models`, and still return before configuration mutation. 4. Implement `--non-interactive` so missing required values cause a clear failure instead of prompting. 5. Add tests that snapshot filesystem state before and after list mode and assert that no files are created, modified, or backed up. 6. Add integration tests confirming that list mode does not change the default model or provider settings. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/alibaba_cloud_model_setup.py:445
Finding
Environment-key mode falsely reports secure credential storage without configuring it<![CDATA[ ## Vulnerability Details **File Location**: `scripts/alibaba_cloud_model_setup.py:445-449`, `scripts/alibaba_cloud_model_setup.py:510-511`, and `scripts/alibaba_cloud_model_setup.py:564-566` **Vulnerability Type**: Misleading and incomplete secret-management implementation **Risk Level**: Medium ### Vulnerable Code ```python if api_key_source == "inline": provider_config["apiKey"] = api_key # else: apiKey will be read from env var ``` ```python api_key_source = args.api_key_source or prompt_api_key_source() env_var = args.env_var or "DASHSCOPE_API_KEY" print(f"🔐 API key source: {api_key_source}") ``` ```python if api_key_source == "env": print(f"\n🔐 API key stored in environment variable: {env_var}") print(f" Add to ~/.bashrc: export {env_var}=YOUR_KEY") ``` The parser also declares persistence options that are not used by the main workflow: ```python parser.add_argument( "--persist-env-shell", action="store_true", help="Write export line to shell profile (default ~/.bashrc) when using env key mode.", ) ``` ```python parser.add_argument( "--persist-env-systemd", action="store_true", help="Write env var to systemd user override and restart service when using env key mode.", ) ``` ### Technical Analysis Environment mode does not read the selected variable, assign the entered API key to it, persist it, or write an environment-variable reference into the provider configuration. The script simply omits the `apiKey` property and later claims that the key was stored. This conflicts with the mandatory rule in `SKILL.md` that environment mode must not write configuration unless environment detection succeeds. No such detection occurs. The declared shell and systemd persistence arguments are also unused. Although this means the script does not actually install persistence, users can reasonably believe that requested credential setup succeeded when it did not. ### Attack Path 1. A user selects the recommended e ...[truncated 1049 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Determine and implement the exact environment-variable reference syntax supported by OpenClaw. 2. Before writing configuration in environment mode, verify that the selected variable exists and contains a nonempty value. 3. If the supplied key is intended to populate the environment, do so only through an explicit and documented mechanism appropriate to the target process. 4. Never claim that a key was stored unless the storage operation completed and was verified. 5. Implement the shell and systemd persistence options securely or remove them from the parser. 6. If shell-profile persistence is implemented, validate the variable name, quote values safely, enforce restrictive profile permissions, avoid duplicate entries, and obtain explicit consent. 7. If systemd persistence is implemented, validate the service name, protect override-file permissions, avoid command construction through a shell, and clearly disclose the service restart. 8. Enforce the documented rule that environment-mode configuration must abort before any file write when environment detection fails. 9. Add tests for missing variables, empty variables, custom variable names, persistence failures, and truthful status reporting. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared description says the skill configures Alibaba/Qwen through a strict interactive flow focused on flagship series, but the documented behavior also includes network API-key validation, backup creation, config mutation, and third-party model support. This mismatch can mislead users and policy systems about the true operational scope, increasing the chance of unreviewed outbound requests or unintended configuration changes.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill instructs execution of a local Python script that can read and write configuration files, invoke shell commands, and make outbound network requests, but the skill metadata declares no tool scope or permissions. This creates a transparency and governance gap: an agent or reviewer cannot accurately constrain or assess what capabilities the skill needs before use.

Session Persistence

Medium
Category
Rogue Agent
Content
- API key storage mode (env-var recommended or inline)
   - Primary model selection
   - Whether to set as default model
4. **Validate API key** against selected site before config write
5. **Backup existing config** before modification
6. **Update config** with provider, models, and defaults
7. **Validate JSON** and report final status
Confidence
84% confidence
Finding
The skill persists changes by backing up and rewriting user configuration, including an example that stores an API key inline in the config file. Persistent modification of authentication material and defaults can expose secrets at rest, alter future agent behavior, and create durable impact beyond the current session.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The documentation explicitly recommends exporting the API key and adding it to shell startup files for persistence, which stores a long-lived secret in plaintext in commonly read config files. This increases exposure through local compromise, backups, dotfile sync, accidental sharing, or process/environment leakage, even though the goal is ordinary setup guidance rather than credential theft.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The argument help text says `--persist-env-shell` writes an export line to a shell profile and `--persist-env-systemd` writes a systemd user override and restarts a service. No code in `main()` or elsewhere uses these flags or performs shell-profile edits, systemd override writes, or service restarts, so the documented behavior contradicts the implementation.

Session Persistence

Medium
Category
Rogue Agent
Content
parser.add_argument(
        "--persist-env-shell",
        action="store_true",
        help="Write export line to shell profile (default ~/.bashrc) when using env key mode.",
    )
    parser.add_argument(
        "--shell-profile",
Confidence
60% 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
93% confidence
Finding
When api_key_source is set to inline, the script writes the API key directly into the JSON configuration file. In a setup skill like this, config files are often backed up, shared, or stored with permissive filesystem access, so embedding long-lived credentials materially increases the risk of credential disclosure and downstream account abuse.

Session Persistence

Medium
Category
Rogue Agent
Content
if api_key_source == "env":
        print(f"\n🔐 API key stored in environment variable: {env_var}")
        print(f"   Add to ~/.bashrc: export {env_var}=YOUR_KEY")
    
    print(f"\n🚀 Next steps:")
    print(f"  1. Restart Gateway: openclaw gateway restart")
Confidence
90% 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.

Natural-Language Policy Violations

Low
Confidence
81% confidence
Finding
Section headings and labels such as `按量付费` and `订阅制` introduce Chinese-language content into an otherwise English document, but the file does not indicate that the content is region-specific or give users a language/locale option. This can violate a language/locale policy when a skill or reference forces a specific language without explicit user opt-in.

Description-Behavior Mismatch

Low
Confidence
89% confidence
Finding
The manifest describes a strict interactive flow for adding or repairing Alibaba Cloud configuration, implying guided prompting. However, the script accepts enough command-line arguments to perform configuration updates without that flow, including config path, API key, plan type, site, model, and default-setting options.

Static analysis

No suspicious patterns detected.