Back to skill

Security audit

公众号内容提取

Security checks for vulnerabilities and agentic risk

Overview

The skill appears intended to fetch WeChat public-account articles, but it has review-worthy risks around shell-command templates, credential handling, and broad outbound fetching.

Install only if you trust the wxpub.aibana.art service and are comfortable sending it your AppID, SecretKey, target account name, and date range. Prefer environment variables or a secret store over typing secrets into chat or command arguments, use narrowly scoped or disposable credentials, choose an output directory you control, and avoid running this skill on account names or paths supplied by someone else without sanitizing them.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:38
Finding

Shell Command Injection Through Untrusted Skill Arguments

Content
View full analysis
') - date.fromisoformat('')).days)" ``` ```bash python3 "/wxpublic_list.py" "" "" "" "" "" ``` ```bash mkdir -p "/images" ``` ```bash python3 "/wxpublic_fetch.py" "" --manifest "/.wxpublic-articles.json" ``` ### Technical Analysis The Skill instructs the agent to interpolate user-controlled parameters directly into shell command strings. Affected inputs include the public-account name, dates, output directory, AppID, and SecretKey. Enclosing an interpolated value in double quotes does not neutralize shell command substitution. If the resulting command contains syntax such as `$(command)` or backticks, the shell can evaluate it before launching the intended program. The date calculation is additionally vulnerable to quoting attacks because values are inserted into both a shell-quoted Python expression and Python string literals. The default output path incorporates the user-controlled public-account name, so command injection may remain possible even when the user does not explicitly supply `--output`. Whether exploitation occurs depends on the agent constructing and executing these command templates as directed. The instructions provide no validation or context-appropriate escaping requirements. ### Attack Path 1. An attacker supplies a crafted argument containing shell syntax, such as a public-account name or output directory containing `$(attacker-command)`. 2. The Skill parser treats the value as an ordinary argument. 3. The agent substitutes the value into one of the documented Bash command templates. 4. Bash performs command substitution while parsing the generated command, i ...[truncated 801 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/wxpublic_fetch.py:20
Finding

Server-Side Request Forgery Through Unvalidated Markdown Image URLs

Content
View full analysis
0: return fname subprocess.run( ["curl", "-s", "-L", "--max-time", "30", "-o", dest, img_url], capture_output=True, ) return fname if (os.path.exists(dest) and os.path.getsize(dest) > 0) else None ``` ```python img_urls = list( dict.fromkeys(u for u in IMG_PATTERN.findall(markdown) if is_image_url(u)) ) with concurrent.futures.ThreadPoolExecutor(max_workers=8) as img_ex: img_futures = {img_ex.submit(download_image, u, images_dir): u for u in img_urls} for f in concurrent.futures.as_completed(img_futures): orig_url = img_futures[f] local_name = f.result() if local_name: markdown = markdown.replace(orig_url, f"./images/{local_name}") ``` ### Technical Analysis The script obtains Markdown from the external conversion service at `anything-md.doocs.org`, extracts HTTP and HTTPS URLs, and downloads URLs considered to be images. The validation is insufficient because any URL whose path ends with a recognized extension is accepted, regardless of hostname. The downloader follows redirects with `curl -L`. It does not validate the original hostname, resolved IP address, or redirect destination. Consequently, a malicious or compromised conversion respon ...[truncated 1878 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/wxpublic_list.py:2
Finding

Platform Secret Exposed Through Command-Line Arguments

Content
View full analysis
/wxpublic_list.py" "" "" "" "" "" ``` ```python """ 用法: python3 wxpublic_list.py ... """ ... if len(sys.argv) != 6: print("用法: python3 wxpublic_list.py ") sys.exit(1) app_id, secure_key, name, start_date, end_date = sys.argv[1:] ``` The README also explicitly recommends command-line credential submission: ```text /wxpublic-fetch <公众号名称> [startDate] [endDate] [--output 目录] [--app-id ] [--secret ] ``` ```text /wxpublic-fetch 拆神 --app-id ak_xxx --secret abc123 ``` ### Technical Analysis The SecretKey is accepted in the Skill invocation and then passed to `wxpublic_list.py` as a positional command-line argument. Command-line secrets may be exposed through: - Agent conversation transcripts and telemetry. - Shell history or command logging. - Process inspection tools while the script is running. - Audit systems that record process creation and arguments. - Error reports or debugging output that captures executed commands. The listing script legitimately sends the AppID and SecretKey to the documented platform endpoint over HTTPS: ```python req = urllib.request.Request( "https://wxpub.aibana.art/fetch", data=payload, headers={"Content-Type": "application/json; charset=utf-8"}, method="POST", ) ``` This network transmission supports the declared authenticated service behavior and was not identified as unauthorized exfiltration. However, exposing the SecretKey in process arguments is unnecessary and exceeds the minimum credential exposure required to ...[truncated 1004 chars]
Remediation
View remediation
`. 8. Document credential rotation and immediate revocation procedures. 9. Where supported by the service, use short-lived, narrowly scoped tokens instead of long-lived reusable secrets. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • 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 (9)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

声明的核心功能是“抓取公众号文章并保存为本地 Markdown 文件”,且完成后要记录保存路径。但提供的代码只是一个列表查询/转发脚本:它把参数提交给外部服务,再输出该服务返回的 JSON。根据代码注释和实现,返回内容是 URLs 和 count,而不是文章正文或 Markdown 文件。代码中没有任何文件写入、Markdown 转换、路径记录等逻辑,因此与声明的主要目的存在实质性不符。

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The script makes an outbound network request to a third-party service, but the capability is apparently undeclared in permissions metadata. In an agent skill, undeclared network access weakens transparency and consent controls, and can cause users or orchestrators to send sensitive inputs to an external service they did not explicitly authorize.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill’s description, usage instructions, status messages, prompts, and confirmation handling are all written exclusively in Chinese, and examples of acceptable replies are centered on Chinese responses. There is no indication that the user can choose another language or that the Chinese-only behavior is a justified locale-specific constraint.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill explicitly instructs the agent to retain all fetched Markdown file paths together with dates and source URLs in conversation context for later reuse. Persisting potentially sensitive local file locations and source metadata beyond the immediate task increases the chance of unintended disclosure to later prompts, context leakage across turns, or over-broad reuse of filesystem details not needed for future answers.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/wxpublic_fetch.py (reported line 61)May include surrounding context.

python
dest = os.path.join(images_dir, fname)
    if os.path.exists(dest) and os.path.getsize(dest) > 0:
        return fname
    subprocess.run(
        ["curl", "-s", "-L", "--max-time", "30", "-o", dest, img_url],
        capture_output=True,
    )

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/wxpublic_fetch.py (reported line 73)May include surrounding context.

python
# A transient html2md error should not discard an article on its first attempt.
    for attempt in range(2):
        try:
            r = subprocess.run(
                [
                    "curl", "-s", "--max-time", "60",
                    "-X", "POST", "https://anything-md.doocs.org/",

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script collects app_id, secure_key, account name, and date range, then posts them directly to an external endpoint. This creates a clear data exfiltration and secret-handling risk: credentials and user query data leave the local environment, and the code provides no explicit warning, consent flow, minimization, or validation of how the remote service stores or uses them.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module docstring and all user-facing CLI messages are written in Chinese, which imposes a specific language on users without opt-in. The file does not indicate that the skill is intended only for a Chinese-speaking or region-specific environment, so this is a natural-language locale policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The script's natural-language docstring and usage/error messages are entirely in Chinese, which imposes a specific language on users without opt-in or alternative locale support. The file does not indicate that this language restriction is intentional or region-specific.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.