Back to skill

Security audit

旺小美数据助手

Security checks for vulnerabilities and agentic risk

Overview

The skill appears purpose-built for Wangxiaobao data lookup, but it needs Review because it can access sensitive customer and recording data while persisting and exposing reusable authentication tokens.

Install only for users who are authorized to access the relevant Wangxiaobao tenants and projects. Treat returned data as sensitive business and personal information, avoid broad or ambiguous prompts, confirm tenant/project switches, and do not run authorization commands in logged or shared environments until token printing and token-file permission handling are fixed.

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

Warning
Location
scripts/auth-manager.js:193
Finding
Reusable Authentication Token Disclosed Through Standard Output<![CDATA[ ## Vulnerability Details **File Location**: `scripts/auth-manager.js:193-208` **Vulnerability Type**: Authentication credential exposure through process output **Risk Level**: Medium ### Vulnerable Code ```javascript if (command === 'clear') { manager.clearToken() } else if (command === 'check') { const token = manager.getSavedToken() if (token) { console.error('✅ 已授权') console.log(token) } else { console.error('❌ 未授权') process.exit(1) } } else { manager.authorize() .then(token => { console.log(token) ``` Both the authorization-status command and the normal authorization flow write the complete token to standard output. ### Technical Analysis The authentication token is a reusable credential sent as the `X-Auth-Token` header by the API client. Printing it to standard output exposes it outside the intended credential-storage boundary. Standard output is commonly captured by: - AI Agent execution transcripts - Parent processes and automation wrappers - CI/CD and diagnostic logs - Terminal recording and monitoring systems - Shell redirection - Centralized log collection services The `check` command only needs to report whether authorization exists, but it returns the credential itself. The normal authorization command also prints the token after retrieving and saving it. This unnecessarily expands the number of locations in which the secret may persist. ### Attack Path 1. A user or Agent invokes `node scripts/auth-manager.js check` or starts the default authorization workflow. 2. The script reads or retrieves the complete authentication token. 3. The token is printed to standard output. 4. An Agent transcript, process wrapper, terminal recorder, or logging service captures the output. 5. An attacker with access to that captured output obtains the token. 6. The attacker supplies the token as `X-Auth-Token` in requests to the Wangxiaobao API. 7. The attacker can access data and operations permitted by the com ...[truncated 897 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove all default output of the complete authentication token. 2. Change the `check` command to return only a status message and an appropriate exit code. 3. Do not print the token after normal authorization; pass it directly between trusted modules in memory. 4. If machine-readable token export is genuinely required, place it behind an explicit opt-in flag such as `--print-token`. 5. Display a security warning before any explicit token export and write it only to a caller-controlled secure channel. 6. Review logs and Agent transcripts created by previous executions and remove exposed credentials. 7. Revoke or rotate tokens that may already have been captured. A safer status implementation would be: ```javascript } else if (command === 'check') { if (manager.getSavedToken()) { console.log('authorized') process.exit(0) } console.log('unauthorized') process.exit(1) } ``` The normal authorization path should confirm success without returning the secret: ```javascript manager.authorize() .then(() => { console.log('Authorization completed successfully.') }) ``` ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/auth-manager.js:155
Finding
Authentication Token File Is Created Before Restrictive Permissions Are Enforced<![CDATA[ ## Vulnerability Details **File Location**: `scripts/auth-manager.js:155-166` **Vulnerability Type**: Insecure plaintext credential-file creation and permission handling **Risk Level**: Medium ### Vulnerable Code ```javascript saveToken(token) { try { fs.writeFileSync(this.tokenPath, token, 'utf-8') try { fs.chmodSync(this.tokenPath, 0o600) } catch (e) { // chmod 在某些系统上可能失败,不影响主流程 } } catch (e) { console.error('保存 token 失败:', e.message) throw e } } ``` ### Technical Analysis The token file is created or overwritten before the code applies mode `0600`. Initial file permissions are therefore derived from the process umask rather than being enforced atomically at creation. This causes two security problems: 1. There is a race window between `writeFileSync` and `chmodSync` in which another local user or process may read the token if the initial mode permits it. 2. Any `chmodSync` failure is silently ignored, allowing authorization to complete while the reusable credential may remain accessible to other users. The credential is stored as plaintext at `~/.wangke-auth-token`. Plaintext storage is documented, but secure permission enforcement is essential because this token authorizes access to sensitive customer and recording data. ### Attack Path 1. A user completes the remote authorization process. 2. `saveToken` creates or overwrites `~/.wangke-auth-token` using permissions derived from the current umask. 3. The initial file mode permits access by another local user, or the later permission change fails. 4. A local attacker or monitoring process reads the token during the race window or after the ignored failure. 5. The attacker replays the token in the `X-Auth-Token` request header. 6. The attacker accesses Wangxiaobao resources allowed by the victim's account. Exploitation requires local access sufficient to read a permissively created file or observe it during the permission-change window. The issue i ...[truncated 681 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Set restrictive permissions as part of the initial file-open operation rather than applying them afterward. 2. Treat any inability to establish or verify secure permissions as a fatal error. 3. Write the credential to a securely created temporary file in the same directory and atomically rename it into place. 4. Verify that the final target is a regular file owned by the current user. 5. Consider using an operating-system credential store instead of a plaintext file. 6. Ensure the containing home directory is not writable by untrusted users. 7. Add automated tests that run under permissive umask settings and verify the final mode is exactly `0600`. At minimum, create the file with an explicit mode: ```javascript saveToken(token) { fs.writeFileSync(this.tokenPath, token, { encoding: 'utf8', mode: 0o600, flag: 'w' }) fs.chmodSync(this.tokenPath, 0o600) const mode = fs.statSync(this.tokenPath).mode & 0o777 if (mode !== 0o600) { throw new Error('Unable to enforce secure token-file permissions.') } } ``` For stronger protection, use a securely created temporary file, verify its ownership and mode, and atomically rename it to `~/.wangke-auth-token`. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (16)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### 3. 清除授权

```bash
rm ~/.wangke-auth-token
# 或
node ~/.claude/skills/wxm-assistant/scripts/auth-manager.js clear
```
Confidence
85% 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).

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill is presented as a data-query assistant, but its documented behavior also includes local HTTP callback handling, QR-based remote authorization, token polling, and persistent credential storage/deletion. This mismatch reduces informed consent and can cause users or reviewers to underestimate the privilege and persistence of the skill, increasing the chance of unsafe token capture or misuse.

Missing User Warnings

High
Confidence
95% confidence
Finding
The skill handles highly sensitive data including customer details, phone numbers, recordings, transcripts, and visit records, yet it does not prominently warn users about the sensitivity of this information or the consequences of exposing it in chat. In this context, missing privacy warnings and consent boundaries make accidental disclosure more dangerous than in a non-sensitive skill.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
如果需要重新授权或更换账号,可以删除授权文件:

```bash
rm ~/.wangke-auth-token
```

或告诉我"清除授权",我会帮你处理。
Confidence
89% confidence
Finding
The skill instructs that saying '清除授权' will cause it to remove a local file via shell (`rm ~/.wangke-auth-token`). Even though the target path is fixed, allowing natural-language-triggered file deletion through shell is dangerous because it normalizes destructive local actions, relies on broad shell capability, and may occur without sufficiently explicit confirmation.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The README describes direct access to sensitive customer, recording, and visit/consultation data but does not present an explicit privacy warning, data-handling limitation, or consent requirement. This omission makes unsafe use more likely by normalizing broad access to personal and potentially sensitive business data without reminding operators to verify authorization and minimize disclosure.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The skill is configured to auto-trigger on very broad, common terms such as '客户', '录音', and '旺小美', which can cause the agent to invoke a high-privilege data-access skill without clear user intent. In a skill that exposes customer records, recordings, and visit data, over-triggering increases the chance of unnecessary access, accidental disclosure, and privacy violations.

Lp3

Medium
Category
MCP Least Privilege
Confidence
81% confidence
Finding
The skill advertises shell/env-capable behavior but does not declare any tool scope or permission boundaries. This creates an authorization gap where the agent may invoke sensitive local capabilities such as reading environment variables or manipulating files without an explicit, reviewable allowlist.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger terms are very broad and include common business words like '客户', '录音', and '来访', which can cause the skill to activate in contexts where the user did not intend to access sensitive enterprise data. Because the skill can retrieve customer records and recordings after authorization, accidental invocation increases privacy and data-exposure risk.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
Natural-language content throughout the eval definitions is exclusively in Chinese, and the file does not state that the skill is region-specific or that users can choose their preferred language. That can violate language/locale policy where a skill implicitly forces one language without documented opt-in or justification.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The prompt '切换到小美研发演示项目' is a broad natural-language trigger that could be matched from ordinary conversation without explicit confirmation that the user intends to invoke this skill. In a skill that can switch tenant/project context and then access customer, visit, and recording data, ambiguous activation increases the risk of unintended context changes and subsequent exposure of sensitive business data.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The prompt '显示接访记录' is overly generic and may overlap with routine requests, making accidental skill activation more likely. Because the skill retrieves visit/consultation records tied to customers and recordings, an unintended invocation could disclose sensitive operational and personal data to an unauthorized or unintended conversational flow.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The customer-list prompt '显示客户列表' is a generic phrase with no scoping or exclusion rules, so it can be triggered by normal conversation fragments. In this skill's context, that can lead directly to disclosure of customer lists from the current tenant/project, which is sensitive CRM-style data and should only be accessed under clearly intentional invocation and authorization constraints.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The skill is described as a read/query assistant for customer, recording, and visit data, but the API client also exposes state-changing session operations to switch project and tenant context. In a multi-tenant system, this broadens the skill from read-only access to cross-context mutation, increasing the chance of unauthorized data access or accidental context pivot if upstream controls or prompts are weak.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The CLI directly exposes session-switching commands, making sensitive context changes easy to invoke even though the stated purpose is data lookup and analysis. In practice this can be abused by prompts, operators, or wrapper automation to move the session into another tenant/project and then query data there, which is especially risky in a customer-data system.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
This code presents its purpose and all user-facing authorization instructions in Chinese only, including the product identity and operational guidance. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is clearly documented and justified, which is not evident here.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
This code presents its usage/help text entirely in Chinese, and other user-facing status/error strings in the file are also Chinese-only. Under the policy for natural-language constraints, forcing a specific language without offering user choice or documenting a locale-specific requirement is a language/locale policy issue.

Static analysis

No suspicious patterns detected.