Back to skill

Security audit

Agent Team

Security checks for vulnerabilities and agentic risk

Overview

This is a mostly coherent Chinese-language multi-agent helper with user-triggered OpenClaw agent launching; it has disclosure and credential-handling quality issues, but no artifact-backed evidence of hidden exfiltration, destructive behavior, or unauthorized persistence.

Before installing, confirm you are comfortable with a Chinese-language skill that sends agent personas, SOUL.md content, and your task/chat text to configured OpenClaw models when you run spawn or chat. Do not hardcode real API keys into greetings.py; the greeting helper should be fixed to use a proper DashScope environment variable and should document its network calls.

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

T09 · Insecure Skill Coding Practices

Warning
Location
greetings.py:17
Finding
Broken and Misleading API Credential Handling## Vulnerability Details **File Location**: `greetings.py`, lines 17–18, 26–27, 35–36, 52–53, 89–94, and 123–127 **Vulnerability Type**: Insecure credential handling and undocumented environment dependency **Risk Level**: Medium ### Vulnerable Code The DashScope agents contain a literal placeholder instead of loading a credential securely: ```python "api_key": "TODO_REPLACE_WITH_ENV", "base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1", ``` The placeholder is placed directly in the HTTP authorization header: ```python req = urllib.request.Request( url, data=data, headers={ 'Content-Type': 'application/json', 'Authorization': f"Bearer {agent['api_key']}" } ) ``` An unrelated environment variable is read only after `main()` has finished, and its value is never used: ```python if __name__ == '__main__': main() import os API_KEY = os.getenv("DEEPSEEK_API_KEY") if not API_KEY: raise ValueError("DEEPSEEK_API_KEY 环境变量未配置") ``` ### Technical Analysis Four DashScope agent definitions use the literal value `TODO_REPLACE_WITH_ENV` as their API key. `call_dashscope()` places that value in an `Authorization: Bearer` header and sends it to the official DashScope HTTPS endpoint. The script later reads `DEEPSEEK_API_KEY`, but this occurs after `main()` and all API calls. The value is not assigned to the agent definitions and is never consumed by `call_dashscope()`. Consequently: 1. DashScope requests are sent with an invalid placeholder credential. 2. Setting `DEEPSEEK_API_KEY` does not authenticate the DashScope requests. 3. Omitting that unrelated variable causes the program to raise an exception after its main processing. 4. The placeholder design may encourage users to insert a real API key directly into source code, exposing it through source distribution, backups, or version-control history. The audited data flow does **not** show envi ...[truncated 1791 chars]
Remediation
## Remediation Suggestions 1. Read the correct DashScope credential from a clearly named environment variable before invoking `main()`: ```python import os DASHSCOPE_API_KEY = os.environ.get("DASHSCOPE_API_KEY") if not DASHSCOPE_API_KEY: raise RuntimeError("DASHSCOPE_API_KEY is not configured") ``` 2. Remove `api_key` values from the static `AGENTS` configuration and pass the credential explicitly to the request function: ```python def call_dashscope(agent: dict, api_key: str) -> str: req = urllib.request.Request( url, data=data, headers={ "Content-Type": "application/json", "Authorization": f"Bearer {api_key}", }, ) ``` 3. Validate credentials before making any network request. Reject empty values and known placeholders such as `TODO_REPLACE_WITH_ENV`. 4. Remove the trailing `DEEPSEEK_API_KEY` block because it is unrelated to DashScope and does not affect authentication. 5. Never instruct users to place API keys directly in source files. Add secret files, if any are introduced, to `.gitignore`, and recommend environment variables or an operating-system secret manager. 6. Document `greetings.py`, its DashScope network destination, the information sent, and the required environment variable in `SKILL.md`. 7. Make greeting-related network access explicitly user-triggered and fail before transmission when configuration is invalid. 8. Avoid exposing authorization headers or credential values in exceptions, logs, or debug output.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (12)

Tainted flow: 'cmd' from input (line 205, user input) → subprocess.run (code execution)

Critical
Category
Data Flow
Content
'--message', f"{system_prompt}\n\n用户:{user_input}"
                ]
                
                result = subprocess.run(cmd, capture_output=True, text=True)
                print(result.stdout)
                print()
Confidence
90% confidence
Finding
External input (network, user) flows to a code execution sink. This enables remote code execution or command injection.

Session Persistence

Medium
Category
Rogue Agent
Content
### 1. 创建目录
```bash
mkdir -p ~/.openclaw/workspace/agents/<agent-name>
```

### 2. 定义 SOUL.md
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.

Context-Inappropriate Capability

Medium
Confidence
77% confidence
Finding
No manifest is available, so the only stated intent comes from the module/help text describing a 'multi-agent team management system' that manages and calls sub-agents. Beyond simple listing/showing metadata, the code actively executes external `openclaw` commands to spawn agent sessions and send chat messages to a model, which is a materially stronger capability than passive local management and is not otherwise justified by a manifest-scoped purpose.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
Task spawning sends the combined system prompt, SOUL.md contents, and user task text to an external subprocess-backed agent session without informing the user that data leaves the script boundary. In environments where SOUL.md or tasks contain internal instructions or sensitive information, this creates an avoidable confidentiality risk.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
]
        
        try:
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=5)
            if result.returncode == 0:
                print(f"{Colors.GREEN}✅ Agent 已启动{Colors.NC}")
                print(result.stdout)
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
Interactive chat forwards both user input and the assembled persona/system prompt, including SOUL.md content, to an external CLI/model without any explicit privacy notice or consent checkpoint. This can expose sensitive local configuration, user prompts, or proprietary persona text to external processing unexpectedly.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
'--message', f"{system_prompt}\n\n用户:{user_input}"
                ]
                
                result = subprocess.run(cmd, capture_output=True, text=True)
                print(result.stdout)
                print()
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
The module description and embedded prompts are written to operate in Chinese, including instructing agents how to greet the user, but there is no indication that language selection is optional or user-configurable. Under the stated policy, forcing a specific language or locale without opt-in is a natural-language policy concern.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The code sends agent prompts to external model providers over the network without any notice, consent flow, or execution-path warning. Even though the current prompts are static, this pattern becomes risky in agent environments because future prompt contents may include user data, internal context, or proprietary instructions that are silently disclosed to third parties.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The file claims to use an environment variable for API key handling, but the actual request path reads credentials from each agent's hardcoded api_key field. This mismatch is dangerous because developers may believe secrets are handled safely while the code remains one edit away from embedding real keys in source control or using placeholder credentials incorrectly.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
The natural-language content throughout the skill file is Chinese-only, including usage instructions and examples. Under the policy rules, forcing a specific language without user opt-in can be a locale/language policy violation when no alternative or opt-in is provided.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The user-facing description, help text, prompts, and status messages are all presented in Chinese, with no option to select another language. This imposes a locale/language constraint on all users without opt-in or a stated region-specific justification.

Static analysis

No suspicious patterns detected.