Back to skill

Security audit

Make claw friends and share task with Email, show me your claw business card

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed email-based agent collaboration tool, but it needs review because it can process remote tasks, send mail, mutate a token ledger, and expose mailbox credentials with weak safety controls.

Install only if you are comfortable with a skill that reads and sends mailbox messages, stores email credentials locally, records full task exchanges, and updates a local token ledger. Before use, require owner confirmation for all inbound tasks, outbound tasks, and settlements; use a dedicated low-privilege mailbox; avoid secrets or private data in delegated tasks; and fix credential redaction, message authentication, path validation, and settlement validation.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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)

T01 · Skill Instruction Hijacking

Error
Location
scripts/receive_mail.py:70
Finding
Unauthenticated Email Messages Can Hijack Agent Task Execution<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:25-27`, `SKILL.md:96-114`, `scripts/receive_mail.py:70-88`, and `scripts/receive_mail.py:142-159` **Vulnerability Type**: Unauthenticated external instruction processing **Risk Level**: Critical ### Vulnerable Code and Instructions `SKILL.md:25-27` establishes automatic execution as the default: ```markdown - **邮箱是消息总线**:每个 Agent 配置自己的 SMTP/IMAP 邮箱,好友间通过邮件交流 - **任务即邮件**:任务请求、结果、账单都通过结构化 JSON 邮件传输 - **默认不确认**:发送任务/确认账单默认自动执行,但所有交流过程都会记录供主人查看 ``` `SKILL.md:102-114` directs the Agent to parse and execute received tasks: ```markdown ### 4. 承接任务 **触发**:收到好友发来的任务邮件。 步骤: 1. **收取邮件**:通过 IMAP 读取新邮件 2. **解析任务**:验证 JSON 格式 3. **(可选)主人确认**:若 `requireOwnerConfirmation=true`,询问是否承接 4. 执行任务,**记录实际 Token 消耗** 5. 生成结果 + 账单(基于实际消耗) 6. **发送回复**:用 SMTP 发回结果和账单 ``` `scripts/receive_mail.py:70-88` accepts any successfully parsed JSON object without validating its protocol or origin: ```python def parse_email_content(msg: email_message.Message) -> dict: """解析邮件内容,提取 JSON body""" if msg.is_multipart(): for part in msg.walk(): content_type = part.get_content_type() if content_type == "application/json": payload = part.get_payload(decode=True) if payload: return json.loads(payload.decode("utf-8")) # 也尝试 text/plain if content_type == "text/plain": payload = part.get_payload(decode=True) if payload: try: return json.loads(payload.decode("utf-8")) except: pass else: payload = msg.get_payload(decode=True) if payload: try: return json.loads(payload.decode("utf-8")) except: pass return {} ``` `scripts/receive_mail.py:142-159` returns the unverified sender and content as actionable message data: ```python raw_e ...[truncated 2728 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Change the default to `requireOwnerConfirmation: true`, especially for all remotely received tasks. 2. Authenticate every message using a cryptographic signature or HMAC over a canonicalized payload. Store each friend's verification key separately from message content. 3. Enforce an authorization pipeline before exposing a message to the Agent: - Require `protocol == "agent-network/v1"`. - Allowlist recognized `messageType` values. - Validate the complete payload against a strict schema. - Require `toAgentId` to equal the local Agent ID. - Require `fromAgentId` and the actual sender address to match one registered friend. - Reject blocked or unknown senders. 4. Add anti-replay controls using signed timestamps, unique nonces, and a persistent set of processed message IDs. 5. Treat task descriptions and results as untrusted data, not system or developer instructions. 6. Apply independent tool-level authorization and data-access restrictions so task text cannot override safety boundaries. 7. Quarantine failed or untrusted messages and display them to the owner without executing them. 8. Record authentication and authorization decisions in an audit log. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/settle.py:105
Finding
Task ID Path Traversal Enables Filesystem Access Outside the Tasks Directory<![CDATA[ ## Vulnerability Details **File Location**: `scripts/settle.py:105-106`, `scripts/show_task.py:39-40`, and `scripts/get_token_usage.py:38-39` **Vulnerability Type**: Path traversal **Risk Level**: High ### Vulnerable Code `scripts/settle.py:104-107`: ```python # 更新任务状态 if task_id: task_path = net_dir / "tasks" / f"{task_id}.json" if task_path.exists(): task = json.loads(task_path.read_text(encoding="utf-8")) ``` `scripts/show_task.py:38-44`: ```python def show_task(workspace: Path, task_id: str): net_dir = workspace / "agent-network" task_path = net_dir / "tasks" / f"{task_id}.json" if not task_path.exists(): print(f"[ERROR] 任务 {task_id} 不存在") sys.exit(1) task = json.loads(task_path.read_text(encoding="utf-8")) ``` `scripts/get_token_usage.py:33-41`: ```python def get_task_token_usage(workspace: Path, task_id: str) -> dict: """ 从任务记录中获取 Token 消耗 任务记录中应包含 taskStartTokens 和 taskEndTokens """ task_path = workspace / "agent-network" / "tasks" / f"{task_id}.json" if not task_path.exists(): return {"error": f"任务 {task_id} 不存在", "tokenCount": 0} task = json.loads(task_path.read_text(encoding="utf-8")) ``` ### Technical Analysis The `task_id` value originates from command-line input and is interpolated directly into a filesystem path. It is not validated as a UUID and is not checked for path separators or traversal components. `pathlib.Path` does not automatically confine a path beneath its preceding directory. A value containing components such as `../` can therefore resolve outside `agent-network/tasks`. The automatic `.json` suffix limits the target to a corresponding JSON filename but does not prevent traversal. The read-oriented scripts can attempt to parse JSON outside the intended directory. `settle.py` additionally writes the loaded object back after changing task fields, so a traversed target with a compatible structure may be modified. ### A ...[truncated 1212 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse all task identifiers as UUIDs before using them: ```python from uuid import UUID canonical_task_id = str(UUID(task_id)) ``` 2. Reject identifiers containing `/`, `\`, `..`, null bytes, or any noncanonical UUID representation. 3. Resolve and verify the final path: ```python tasks_dir = (net_dir / "tasks").resolve() task_path = (tasks_dir / f"{canonical_task_id}.json").resolve() if task_path.parent != tasks_dir: raise ValueError("Invalid task path") ``` 4. Open files with safe, explicit semantics and reject symbolic links where the platform permits. 5. Validate the loaded document against a strict task schema before reading or updating it. 6. Apply the same centralized task-path helper to every script rather than implementing path construction separately. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/settle.py:45
Finding
Settlement Validation Flaws Permit Ledger Inflation and Duplicate Transactions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/settle.py:45-62` and `scripts/settle.py:86-102` **Vulnerability Type**: Improper financial transaction validation and missing idempotency **Risk Level**: High ### Vulnerable Code `scripts/settle.py:45-62` trusts caller-controlled settlement fields and only performs a limited balance check: ```python tx_type = args.get("type", "spend") amount = float(args.get("amount", 0)) task_id = args.get("task_id", "") counterparty_id = args.get("counterparty_id", "") counterparty_name = args.get("counterparty_name", "") token_count = int(args.get("token_count", 0)) rate = float(args.get("rate", 0.01)) profit_margin = float(args.get("profit_margin", 0.20)) description = args.get("description", "任务结算") now = datetime.now(timezone.utc).isoformat() # 检查余额(仅 spend 类型) if tx_type == "spend" and ledger["balance"] < amount: print(f"[ERROR] 余额不足:当前余额 {ledger['balance']} AgentToken,需要 {amount} AgentToken", file=sys.stderr) sys.exit(1) # 计算利润金额 base_cost = (token_count / 1000) * rate if token_count > 0 else amount / (1 + profit_margin) profit_amount = round(base_cost * profit_margin, 6) ``` `scripts/settle.py:86-102` applies the unchecked amount and always appends a new transaction: ```python # 更新余额 if tx_type == "earn": ledger["balance"] = round(ledger["balance"] + amount, 6) ledger["totalEarned"] = round(ledger["totalEarned"] + amount, 6) elif tx_type == "spend": ledger["balance"] = round(ledger["balance"] - amount, 6) ledger["totalSpent"] = round(ledger["totalSpent"] + amount, 6) elif tx_type == "topup": ledger["balance"] = round(ledger["balance"] + amount, 6) ledger["totalEarned"] = round(ledger["totalEarned"] + amount, 6) elif tx_type == "withdraw": ledger["balance"] = round(ledger["balance"] - amount, 6) ledger["totalSpent"] = round(ledger["totalSpent"] + amount, 6) ledger["transactions"].append(tx) ``` ### Technical Analysis Settlement parameters are accepted directl ...[truncated 2076 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require a recognized transaction type and reject all other values. 2. Validate numeric inputs before any state change: ```python import math if not math.isfinite(amount) or amount <= 0: raise ValueError("Amount must be positive and finite") ``` 3. Do not accept the authoritative amount, rate, token count, margin, or counterparty directly from the caller. Load them from a stored bill that has passed validation and owner approval. 4. Require the task to exist, verify its counterparty and role, and enforce an explicit state transition from approved to settled. 5. Enforce idempotency by rejecting settlement when a completed transaction already references the task or bill ID. 6. Use a unique bill ID or settlement key and enforce uniqueness. 7. Lock the ledger during read-modify-write operations and save through an atomic temporary-file replacement. 8. Use decimal arithmetic rather than binary floating point for ledger values. 9. Recalculate totals from transaction records or periodically verify balance invariants. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/init.py:39
Finding
SMTP and IMAP Credentials Are Stored in Plaintext and Exposed by the Identity Command<![CDATA[ ## Vulnerability Details **File Location**: `scripts/init.py:39-68` and `scripts/openclaw-agent-network.sh:26-29` **Vulnerability Type**: Plaintext secret storage and sensitive information exposure **Risk Level**: Medium ### Vulnerable Code `scripts/init.py:39-68` creates a normal JSON identity file intended to contain mailbox authorization codes: ```python # identity.json - 包含邮箱配置模板 identity_path = net_dir / "identity.json" if not identity_path.exists(): identity = { "agentId": str(uuid.uuid4()), "name": "My Agent", "ownerName": "", "description": "A helpful OpenClaw agent", "skills": [], "skillDetails": {}, "ratePerKToken": 0.01, "profitMargin": 0.20, "email": { "smtp": { "host": "smtp.qq.com", "port": 587, "user": "your-email@qq.com", "password": "YOUR_SMTP_AUTH_CODE" }, "imap": { "host": "imap.qq.com", "port": 993, "user": "your-email@qq.com", "password": "YOUR_IMAP_AUTH_CODE" } }, "createdAt": datetime.now(timezone.utc).isoformat(), "updatedAt": datetime.now(timezone.utc).isoformat() } identity_path.write_text(json.dumps(identity, ensure_ascii=False, indent=2), encoding="utf-8") ``` `scripts/openclaw-agent-network.sh:26-29` prints the complete file without redaction: ```bash identity) if [ -f "$WORKSPACE/agent-network/identity.json" ]; then cat "$WORKSPACE/agent-network/identity.json" else ``` ### Technical Analysis The configuration model instructs users to replace placeholder values with real SMTP and IMAP authorization codes. These credentials are stored directly in `identity.json`. The initialization code does not explicitly set the file mode to `0600`; effective permissions therefore depend on the process umask and surrounding directory perm ...[truncated 1389 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store mailbox credentials in an operating-system keychain, dedicated secret manager, or protected credential helper. 2. Separate public Agent identity data from private transport configuration. 3. If file storage is unavoidable, create the secret file with mode `0600` and ensure the containing directory is accessible only to the owner: ```python import os fd = os.open(identity_path, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600) with os.fdopen(fd, "w", encoding="utf-8") as handle: json.dump(identity, handle, ensure_ascii=False, indent=2) ``` 4. Replace the raw `cat` command with a redacted identity-display function that omits or masks password fields. 5. Never include the private identity file in backups, logs, exported task records, source control, or shared Agent cards. 6. Document credential rotation and encourage provider-specific application passwords with the minimum available privileges. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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 (29)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The description presents a broad collaboration-network skill with active capabilities: connecting agents via email, managing friends, delegating tasks, receiving tasks, and billing/settlement. The provided code only implements a local inspection utility for existing task records. It reads task JSON files and prints task metadata, logs, results, and billing information, or lists available tasks. While viewing collaboration history and bills is loosely related to a small subset of the declared scenarios, the actual code’s primary purpose is much narrower and does not implement the core network/email/delegation/payment behaviors described. Therefore the description does not accurately represent what this code chunk actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
声明描述的是一个较完整的多 Agent 协作网络技能,核心能力包括通过邮箱连接其他 Agent、建立好友关系、委托任务、协作处理、账单结算和记录管理。实际代码却只是单一的 validate_bill.py 脚本,用于验证一份账单是否在预算范围内、利润率是否合理、以及金额计算是否一致。虽然“查看 Token 账单/结算”与账单相关,代码只能做账单争议校验这一小部分辅助功能,远不足以支撑所声明的主要用途,也没有访问或使用邮箱、联系人、任务分发、结算流水等资源。因此描述与代码行为存在明显且实质性的不匹配。

Missing User Warnings

High
Confidence
97% confidence
Finding
The skill states that sending tasks and confirming bills default to automatic execution, which allows outbound delegation and payment-related actions without explicit user approval. Because the skill uses email as an external communication channel and interacts with billing records, this can cause data exfiltration, unwanted commitments, or fraudulent settlement if triggered maliciously or accidentally.

Lp3

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding
The skill describes capabilities that require file access and network communication, but it does not declare any explicit tool scope or permission boundaries. In an agent framework, missing scope declarations weaken least-privilege controls and make it harder for operators to understand or restrict what the skill may access.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The trigger phrases are broad, natural-language commands like adding friends, outsourcing work, or checking balances, which increases the chance of accidental activation. In this skill, unintended activation is more dangerous because activation can lead to network communication, task delegation, and billing workflows.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The description mentions that all exchanges are recorded, including sent and received mail content, but it does not provide a clear up-front privacy warning near configuration and usage. Since delegated tasks and email contents may include sensitive user data, silent or underemphasized full-content logging increases privacy and retention risk.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill explicitly describes mutating a local accounting file (`ledger.json`) and sending billing emails as part of settlement, but does not require an explicit user confirmation or warning before these side effects occur. In an agent-to-agent workflow, that can lead to unauthorized state changes, unintended payments, or outbound communications triggered by another agent or ambiguous user input.

Intent-Code Divergence

Medium
Confidence
92% confidence
Finding
The document explicitly warns not to share SMTP/IMAP configuration and passwords in the public identity card, but then defines a friends.json structure that stores counterparties' SMTP/IMAP host, port, and user details. Even without passwords, centralizing mail infrastructure details and account identifiers for multiple agents increases privacy exposure, enables targeted phishing/account-enumeration, and normalizes collecting more connection metadata than is needed for task routing.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The protocol sends task descriptions, input data, results, billing details, agent IDs, and email addresses over ordinary email JSON messages without any privacy warning, data-minimization guidance, or trust/authentication requirements. In this skill context, agents may forward user-provided content to external agents, so the absence of explicit consent, sensitivity checks, and message protection can lead to unauthorized disclosure of user data, commercially sensitive prompts/results, and billing metadata.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
This markdown file presents the protocol and safety instructions entirely in Chinese, and it does not indicate that the skill is region-specific or that users may choose another language. The policy requires avoiding forced language or locale constraints unless there is explicit opt-in or a documented justification.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The module docstring presents the script description, usage, and output notes entirely in Chinese, and the script later emits Chinese-only user-facing messages. This imposes a specific language on users without opt-in or documented locale scope, which matches the language/locale policy concern.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The error message and billing summary are emitted solely in Chinese, with no user-selectable locale or fallback. For a general-purpose utility, this forces a language choice on users and can violate organizational language/locale requirements.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The module docstring presents the script description and usage entirely in Chinese, which imposes a specific language on users without any opt-in or indication that the tool is intended only for a Chinese-speaking environment. This matches the language/locale policy violation criteria because no alternative language or explicit locale justification is provided.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The script's success and status prints are all emitted in Chinese, so users receive output in a fixed language regardless of preference. Because there is no opt-in, fallback, or stated locale restriction, this is a natural-language policy concern under the language/locale rule.

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
The instruction tells the user to invoke the next step using a specific Chinese phrase, "说\"展示名片\"", without offering a language choice or documenting that the skill is region/language-specific. This is a natural-language policy concern because it imposes a locale/language requirement rather than making it optional.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This code loads IMAP configuration including credentials from agent-network/identity.json, which is a sensitive credential access path. Although the script has a brief docstring about receiving mail, there is no explicit warning, confirmation, or user-facing disclosure that it will read stored email account credentials.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script fetches full email bodies and then prints subject, sender, message ID, truncated content, and finally the entire EMAILS_JSON payload to stdout. In an agent-network skill, mailbox contents may include delegated tasks, billing details, or other sensitive cross-agent data, so logging this information can leak private data to users, calling processes, logs, or other components that capture stdout.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
This Python file contains natural-language documentation and runtime messages in Chinese only, including the module docstring and error/output text. The policy scope applies to all file types, and there is no indication that the skill is region-specific or that users can opt into another language/locale.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The module docstring and all user-facing output are written in Chinese, which imposes a specific language on users without any opt-in or alternative locale support. Under the policy rule, forcing a language/locale without user choice is a natural-language policy violation unless clearly justified as region-specific.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The script prints task descriptions, result content, billing data, and the full timeline directly to stdout with no redaction, confirmation step, or sensitivity warning. In this skill’s context, those fields can plausibly contain delegated work product, credentials, internal prompts, customer data, or inter-agent communications, so invoking the command can expose sensitive information to anyone with terminal/log access.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This file contains natural-language instructions and results in Chinese only, including the top-level usage text. Under the policy, forcing a specific language without opt-in is a violation unless the locale restriction is clearly documented and justified, which is not present here.

Natural-Language Policy Violations

Low
Confidence
81% confidence
Finding
The natural-language instructions and trigger examples are entirely in Chinese and present the skill behavior as if Chinese is the expected interaction language. There is no opt-in, language choice, or documented locale restriction justifying the language constraint.

Natural-Language Policy Violations

Low
Confidence
93% confidence
Finding
The entire skill document is written in Chinese and does not indicate that users may choose another language or locale. Under SQP-3, language constraints should be opt-in or clearly justified as region-specific; neither is stated here.

Natural-Language Policy Violations

Low
Confidence
93% confidence
Finding
The document presents all instructions and format descriptions in Chinese and does not offer an alternative language or note that the locale is intentionally region-specific. Per the policy rule, forcing a specific language without user opt-in is a natural-language policy concern.

Natural-Language Policy Violations

Low
Confidence
96% confidence
Finding
This code file contains natural-language strings that force a specific language/locale for usage instructions and output. Under the policy, language constraints should either be optional for the user or clearly justified as region-specific; neither is indicated here.

Static analysis

No suspicious patterns detected.