Back to skill

Security audit

微信文章读取

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent article-reading purpose, but its helper script can turn a user-supplied URL into shell command execution.

Review carefully before installing. The skill is not showing persistence or deliberate data theft, but it should not be used in its current form because a crafted URL could make the host run unintended shell commands or contact non-WeChat network targets. A safer version should validate HTTPS mp.weixin.qq.com URLs, reject off-domain redirects, and avoid shell=True.

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

Error
Location
scripts/read_weixin_article.py:29
Finding

Arbitrary Command Execution Through Shell Command Injection

Content
View full analysis

Vulnerability Details

File Location: scripts/read_weixin_article.py, lines 29-35
Vulnerability Type: OS command injection caused by unsafe shell command construction
Risk Level: Critical

Vulnerable Code

python
# Use curl to fetch the page
cmd = f'curl -s -L --max-time 20'
for key, value in headers.items():
    cmd += f' -H "{key}: {value}"'
cmd += f' "{url}"'

import subprocess
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)

Technical Analysis

The user-controlled url argument is interpolated directly into a command string and then passed to subprocess.run with shell=True. Quoting the URL with double quotation marks does not make it safe because an attacker can include another double quote followed by shell metacharacters.

The shell parses the resulting string rather than passing the URL directly to curl. Consequently, crafted input can terminate the intended URL argument and introduce arbitrary commands. No escaping, allowlist validation, or shell-safe argument construction is performed.

Attack Path

  1. An attacker supplies a crafted value as the article URL.
  2. The value contains a closing double quote, shell command separators, and an injected command.
  3. The script appends the value directly to cmd.
  4. subprocess.run(..., shell=True) asks the system shell to parse the complete command.
  5. The shell executes both the intended curl invocation and the attacker-supplied command.

A conceptual malicious argument is:

text
"; attacker-controlled-command; #

The exact command can be adapted to the operating system and the permissions of the process.

Impact Assessment

Successful exploitation provides arbitrary command execution with the same operating-system identity and privileges as the Agent or user running the Skill. Depending on those privileges, an attacker could:

  • Read local files, environment variables, to ...[truncated 421 chars]
Remediation
View remediation

Remediation Suggestions

Eliminate shell interpretation entirely. Pass each argument as a separate list element and keep shell=False:

python
command = ["curl", "-s", "-L", "--max-time", "20"]
for key, value in headers.items():
    command.extend(["-H", f"{key}: {value}"])
command.append(url)

result = subprocess.run(
    command,
    shell=False,
    capture_output=True,
    text=True,
    timeout=25,
    check=False,
)

Prefer a maintained Python HTTP client so no external command is required. In addition:

  • Apply strict URL validation independently of command construction.
  • Permit only the expected HTTPS origin and paths.
  • Do not attempt to secure this code solely through manual shell escaping.
  • Run the Skill under a minimally privileged account with restricted filesystem and network access.
  • Add regression tests containing quotes, command separators, substitutions, newlines, and other shell metacharacters.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/read_weixin_article.py:29
Finding

Server-Side Request Forgery Through Unrestricted URL Fetching and Redirects

Content
View full analysis

Vulnerability Details

File Location: scripts/read_weixin_article.py, lines 29-35 and 78-84
Vulnerability Type: Unrestricted outbound request and server-side request forgery
Risk Level: High

Vulnerable Code

python
# Use curl to fetch the page
cmd = f'curl -s -L --max-time 20'
for key, value in headers.items():
    cmd += f' -H "{key}: {value}"'
cmd += f' "{url}"'

import subprocess
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
python
if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: python3 read_weixin_article.py <wechat-article-url>")
        sys.exit(1)

    url = sys.argv[1]
    content = read_weixin_article(url)
    print(content)

Technical Analysis

Although the Skill is documented as a reader for mp.weixin.qq.com, the implementation accepts any command-line URL without validating its scheme, hostname, port, resolved address, or path. It also invokes curl with -L, which automatically follows redirects without revalidating each destination.

This permits the process to request resources beyond the declared WeChat article domain. Depending on the protocols supported by the installed curl build, the input may also permit schemes other than HTTPS. An initially acceptable-looking endpoint could redirect to a loopback, private, link-local, or otherwise sensitive destination.

Returned HTML is parsed and portions of it may be printed. Therefore, content from a reachable internal endpoint can be disclosed when it contains one of the expected article containers, a matching article-related div, or suitable Open Graph metadata.

Attack Path

  1. An attacker supplies a direct internal URL or a URL under attacker control.
  2. Alternatively, the attacker uses an external endpoint that redirects to an internal or sensitive destination.
  3. The script sends the URL to curl without destination validat ...[truncated 1362 chars]
Remediation
View remediation

Remediation Suggestions

Enforce the documented destination policy before making any request:

  • Accept only the https scheme.
  • Require the normalized hostname to equal mp.weixin.qq.com.
  • Reject embedded credentials, IP-literal hosts, fragments, and nonstandard ports.
  • Resolve the hostname and reject loopback, private, link-local, multicast, reserved, and unspecified addresses.
  • Protect against DNS rebinding by connecting only to validated resolved addresses while preserving TLS hostname verification.
  • Disable automatic redirects or validate the scheme, hostname, port, and resolved address of every redirect target.
  • Reject redirects away from the approved WeChat origin.
  • Configure network-level egress controls to deny access to internal and metadata address ranges.
  • Restrict response size and use explicit connection and read timeouts.
  • Permit only HTTP and HTTPS in the HTTP client configuration, with HTTPS required by policy.

A URL parser such as urllib.parse.urlsplit should be used for structural validation. Validation must not rely on substring matching because hostnames such as mp.weixin.qq.com.attacker.example are not part of the approved origin.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
Findings (8)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
99% confidence
Finding

This is true tool-parameter abuse: untrusted user input is passed into a powerful system tool invocation in a way that lets the user influence shell behavior. Because the skill accepts URLs from users and then interpolates them into a shell command, an attacker can potentially execute arbitrary commands or coerce the environment into making unintended requests. The article-reading context does not justify this level of system access, making the finding more dangerous.

Content

Scanner excerpt · scripts/read_weixin_article.py (reported line 33)May include surrounding context.

python
cmd += f' "{url}"'
    
    import subprocess
    result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
    
    if result.returncode != 0:
        return f"Error fetching URL: {result.stderr}"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill declares shell-capable behavior but does not specify any tool scope or permissions boundaries. That omission increases the chance the agent can invoke shell access more broadly than intended, reducing reviewability and making misuse or prompt-triggered execution harder to contain.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The activation conditions are broad enough to trigger on common requests involving links, summaries, or article extraction, which can cause the skill to run when the user did not clearly request this specific capability. In this case that is more concerning because the skill is designed to bypass anti-scraping protections, so accidental activation could lead to unauthorized retrieval behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill description presents the capability as ordinary article reading while omitting a clear user-facing warning that it attempts to bypass anti-scraping restrictions. That lack of transparency can mislead users and reviewers about legal, policy, and security implications, especially since the skill explicitly advertises defeating platform protections.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill uses a general-purpose shell command to perform network access, which grants more capability than needed for simply reading web content. This broadens the attack surface because any flaw in command construction or input handling can turn a simple fetch operation into arbitrary command execution or unintended system interaction. Given the stated purpose of bypassing anti-scraping protections, the design already pushes toward riskier behavior than a normal content reader.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code performs a network fetch of a user-supplied URL through a shell command without confirmation, validation, or restriction. Even aside from command injection, this enables server-side request forgery style behavior and can be abused to make the host contact arbitrary endpoints, which is more dangerous in an agent environment where users can trigger the skill with supplied links. The shell-based implementation further raises the severity because it compounds network abuse with command-execution risk.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
99% confidence
Finding

This is a true command-injection vulnerability. The code builds a shell command string by concatenating attacker-controlled input (the URL) and executes it with shell=True, so a crafted URL containing shell metacharacters or command substitution can execute arbitrary OS commands on the host. In the context of an agent skill that automatically activates on user-provided links, this becomes especially dangerous because untrusted input flows directly into shell execution.

Content

Scanner excerpt · scripts/read_weixin_article.py (reported line 33)May include surrounding context.

python
cmd += f' "{url}"'
    
    import subprocess
    result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
    
    if result.returncode != 0:
        return f"Error fetching URL: {result.stderr}"

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The Accept-Language header is hard-coded to 'zh-CN,zh;q=0.9', which imposes a specific language/locale preference on all requests. This is a natural-language policy concern because the skill does not offer user opt-in or explain why a Chinese locale must be forced.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.