Back to skill

Security audit

发票查重

Security checks for vulnerabilities and agentic risk

Overview

This invoice-checking skill mostly matches its stated purpose, but it handles API keys unsafely and includes an undeclared file-upload helper.

Review carefully before installing. Use this only if you are comfortable sending invoice details and an API key to the stated external service. Do not paste real API keys into chat; prefer a scoped, revocable key set only for the current run or stored in a proper secret manager. The publisher should remove or clearly scope the file-upload helper, replace the credential-shaped example key, and avoid writing secrets into shell startup files by default.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:53
Finding

Unsafe API Key Disclosure and Persistent Plaintext Storage

Content
View full analysis
` writes it to the user environment, followed by `export ZXT_API_KEY=` for the current session. - macOS/Linux: append `export ZXT_API_KEY=` to `~/.bashrc` or `~/.zshrc`, depending on the shell, and execute `export ZXT_API_KEY=` for the current session. ``` The snippet above is an English rendering of the instructions at the cited location. The original commands and placeholder syntax are preserved. ### Technical Analysis The Skill instructs users to send an authentication secret through the conversation and then persist that secret in plaintext using `setx` or a shell startup file. This exceeds the minimum privileges required for invoice deduplication. The implementation already supports a process-scoped `ZXT_API_KEY` environment variable and a `--api-key` argument, so permanent modification of user configuration is unnecessary. Conversation content may be retained in agent histories, telemetry, debugging logs, or support exports. Shell startup files are also commonly readable by applications running as the same user and may be copied into backups or configuration repositories. The documented commands interpolate `` without demonstrating safe shell quoting. If an agent substitutes attacker-controlled content directly into a shell command, shell metacharacters in the supplied value could potentially introduce additional commands. ### Attack Path 1. A user is instructed to provide the API key directly through the conversation. 2. The cr ...[truncated 1249 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:141
Finding

Plausible Hardcoded API Credential in Documentation Examples

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
common.py:45
Finding

Undeclared Arbitrary Local File Upload Capability

Content
View full analysis
dict: file_size = os.path.getsize(file_path) if file_size > MAX_FILE_SIZE: return {"status": "-1", "message": f"File too large: {file_size / 1024 / 1024:.1f}MB; limit is 10MB"} boundary = uuid.uuid4().hex file_name = os.path.basename(file_path) with open(file_path, "rb") as f: file_data = f.read() parts = [] parts.append( f"--{boundary}\r\n" f'Content-Disposition: form-data; name="apiKey"\r\n' f"\r\n{api_key}\r\n".encode() ) parts.append( f"--{boundary}\r\n" f'Content-Disposition: form-data; name="file"; filename="{file_name}"\r\n' f"Content-Type: application/octet-stream\r\n" f"\r\n".encode() ) parts.append(file_data) parts.append(f"\r\n--{boundary}--\r\n".encode()) body = b"".join(parts) url = f"{BASE_URL}{path}" req = urllib.request.Request( url, data=body, headers={"Content-Type": f"multipart/form-data; boundary={boundary}"}, method="POST", ) try: with urllib.request.urlopen(req, timeout=60) as resp: return json.loads(resp.read().decode("utf-8")) ``` The displayed error text is translated into English; the executable behavior is otherwise represented directly. ### Technical Analysis `post_file` accepts an unrestricted caller-supplied filesystem path, opens the corresponding file, reads up to 10 MB into memory, and sends the complete content to a caller-selected path under `https://skill.quandianfapiao.com`. The declared invoice-deduplication functionality requires structured JSON requests containing invoice fields. `invoice_dedup.py` does not import or call `post_fil ...[truncated 2014 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (9)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill clearly expects access to environment variables and remote network APIs, yet it declares no explicit tool scope such as permissions or allowed-tools. This creates an authorization ambiguity where an agent may use broader capabilities than users expect, increasing the risk of unintended credential access or external data transmission.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill explicitly asks the user to paste their apiKey into chat so the agent can configure and use it. Sending credentials through chat unnecessarily exposes secrets to conversation logs, downstream integrations, and any components that can access transcript history.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill instructs persisting the provided API key into user shell startup files or user-level environment storage, but gives no warning that this leaves credentials stored long-term on disk and potentially exposed to other local processes or future sessions. Persisting secrets by default is dangerous because it broadens the exposure window well beyond the immediate task.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The function uploads arbitrary local file contents together with an API key to a hard-coded remote server, but the code itself provides no consent, destination transparency, or safeguards around what files may be sent. In a skill context, this creates a real data exfiltration risk because invoice files commonly contain sensitive financial and identity information, and the helper can be reused by other scripts to transmit local data silently.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill transmits sensitive business data and the user's apiKey to a remote service via the helper post() call, but the code provides no inline warning, consent step, or disclosure at the point of use. In this context, invoice numbers, dates, codes, and amounts are potentially sensitive financial records, so silent exfiltration to a third-party endpoint creates privacy and credential-handling risk even if the endpoint is expected functionality.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The setup text explicitly instructs the user to send their apiKey to the assistant so it can configure and execute the skill. Asking users to disclose secrets directly to an assistant normalizes unsafe secret-sharing behavior, increases the chance of credential leakage through logs or chat history, and can enable unauthorized use of the external invoicing account.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The natural-language instructions, prompts, and examples are all presented in Chinese, which effectively forces a specific language for using the skill. There is no indication that the user may choose another language or that the locale restriction is intentional and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The module docstring and all user-visible status/error/output strings are hard-coded in Chinese, which implies the skill's responses are constrained to a specific language. There is no indication in this file that the user can choose a different language or that the locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

All user-facing descriptions, help text, and error/instruction messages are in Chinese, which effectively forces a specific language for interaction. The file does not offer a language option or explain that the skill is intentionally restricted to a Chinese-language context.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.