Back to skill

Security audit

微信公众号文章读取器

Security checks for vulnerabilities and agentic risk

Overview

This WeChat article skill is mostly purpose-aligned, but it asks for highly sensitive session cookies and uses unsafe network handling that could expose credentials or reach unintended hosts.

Review this skill carefully before installing. Do not paste full WeChat browser cookie exports into an agent or store them in this skill directory unless you accept possible account-session exposure. Prefer using a fresh, low-privilege, short-lived API key, remove the packaged key, restrict fetches to trusted WeChat hosts, and avoid the trends path until TLS verification is 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 (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/fetch_wechat_article.py:118
Finding

WeChat Session Cookie Can Be Sent to an Attacker-Controlled Host

Content
View full analysis
tuple: import requests as req if not url.startswith("https://mp.weixin.qq.com"): url = "https://mp.weixin.qq.com/s/" + url.split("/s/")[-1] headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Cookie": cookie, "Referer": "https://mp.weixin.qq.com/", "Accept": "text/html,application/xhtml+xml,*/*", "Accept-Language": "zh-CN,zh;q=0.9", } r = req.get(url, headers=headers, allow_redirects=True, timeout=30) ``` ### Technical Analysis The code decides whether a URL is a trusted WeChat URL by performing a string-prefix comparison: ```python url.startswith("https://mp.weixin.qq.com") ``` A string prefix is not equivalent to hostname validation. URLs such as the following pass this check even though their effective destination is controlled by an attacker: ```text https://mp.weixin.qq.com.attacker.example/article https://mp.weixin.qq.com@attacker.example/article ``` The function then attaches the authenticated WeChat session cookie to the request. The use of `allow_redirects=True` additionally means redirect handling is not constrained to the trusted WeChat origin. This behavior exceeds the minimum privileges required to retrieve public article content. A privileged WeChat administrative session should not be attached to a destination unless its parsed hostname has been strictly validated. ### Attack Path 1. The victim configures authenticated WeChat Platform cookies as directed by the Skill. 2. An attacker supplies a URL beginning with the trusted string but resolving to an attacker-controlled hostname. 3. The unauthentic ...[truncated 861 chars]
Remediation
View remediation
str: parsed = urlsplit(url) if parsed.scheme != "https": raise ValueError("Only HTTPS URLs are allowed") if parsed.hostname != "mp.weixin.qq.com": raise ValueError("Untrusted hostname") if parsed.username or parsed.password: raise ValueError("Embedded credentials are prohibited") if parsed.port not in (None, 443): raise ValueError("Unexpected port") return url ``` ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/fetch_wechat_article.py:147
Finding

Unrestricted curl Destinations Enable Server-Side Request Forgery

Content
View full analysis
tuple: import subprocess strategies = [ {"ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36", "referer": "https://mp.weixin.qq.com/"}, {"ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1", "referer": "https://www.google.com/"}, {"ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15", "referer": "https://www.google.com/"}, ] for strat in strategies: cmd = ["curl", "-s", "-L", "-A", strat["ua"], "-H", f"Referer: {strat['referer']}", "--connect-timeout", "15", "--max-time", "30", url] result = subprocess.run(cmd, capture_output=True, text=False) ``` A second equivalent curl call is present at `scripts/fetch_wechat_article.py:213-221`. ### Technical Analysis The user-supplied URL is passed directly to curl without restrictions on: - URL scheme - Destination hostname - Resolved IP address - Destination port - Redirect target - Access to loopback, private, or link-local networks The `-L` option permits redirects, so even an initially public URL can redirect to an internal service. Using an argument array prevents ordinary shell metacharacter injection, but it does not prevent SSRF. Depending on the protocols supported by the installed curl build, non-HTTP schemes may also be available because no `--proto` or `--proto-redir` restrictions are configured. The project contains `sanitize_http_url`, but this helper only checks the scheme and is not applied to these fetch paths. It would also be insufficient ...[truncated 1271 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/core/http_client.py:110
Finding

Certificate and Hostname Verification Are Disabled for the Trends API

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/skill.env:2
Finding

API Credential Is Hardcoded in the Distributed Environment File

Content
View full analysis
MpTextAPI: global _client if _client is None: env_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), "skill.env") load_dotenv(env_file) _client = MpTextAPI() return _client ``` It is added to outgoing requests at `scripts/mptext_api.py:105-106`: ```python if self.api_key: self.session.headers['X-Auth-Key'] = self.api_key ``` ### Technical Analysis A concrete API key is stored directly in the Skill package. Anyone who can download, inspect, cache, or redistribute the Skill can recover and reuse it. The key is loaded automatically and placed in the `X-Auth-Key` header for requests to the mptext service. Even if the provider describes the key as short-lived, committing it remains unsafe because its validity cannot be guaranteed at review or deployment time, and future replacements may be committed in the same location. ### Attack Path 1. An attacker obtains a copy of the Skill package or repository. 2. The attacker reads `scripts/skill.env`. 3. The attacker extracts the API key. 4. The attacker sends independent requests to the mptext API using the key. 5. The legitimate owner may experience quota exhaustion, attribution of attacker requests, or service charges. ### Impact Assessment The exposed credential may enable unauthorized use of the mptext API under the credential owner's identity and quota. Potential consequences include: - Quota depletion - Unexpected billing - Abuse attributed to the l ...[truncated 200 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
env-guide.md:31
Finding

Setup Instructions Request Full Browser Session Export and Plaintext Storage

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (60)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

声明描述聚焦于微信公众号文章抓取、公众号搜索和文章分析,这暗示的是面向微信公众平台相关数据的业务能力。实际代码并未体现任何微信公众号、mp.weixin.qq.com、文章解析、搜索或分析逻辑;它提供的是一个通用 HTTP/HTTPS 抓取底层组件。更重要的是,该组件包含明显未声明的规避性能力:使用 raw socket、server_hostname=None 禁用 SNI、关闭 hostname/certificate 校验,以“anti-crawling bypass”为目的访问远程主机。这属于比声明更广泛且更敏感的网络访问/反爬绕过能力,不只是普通的支撑性实现细节。因此描述与代码行为存在实质性不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的是一个与微信公众号文章抓取、搜索和分析相关的技能,但提供的代码片段只是底层安全辅助函数,作用是清洗 URL、HTML href、公众号账号 ID 和文件名,防止 javascript/data 注入、属性注入及路径遍历。这些属于通用支持性安全实现,并不能体现声明中的核心能力。由于实际代码的主要用途与声明的主要用途明显不同,构成描述与行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

代码的核心功能是输入一个 mp.weixin.qq.com 文章 URL,抓取并提取该文章正文文本与标题。它确实覆盖了声明中的“抓取微信公众号文章”这一部分,也与触发场景中的文章链接相关。但声明还包含多项更广泛能力:搜索公众号、获取文章列表、爆款查询与分析,这些在提供的代码中完全没有实现迹象。代码没有调用公众号搜索接口、没有列举账号文章列表、没有做阅读量/点赞等爆款指标查询,也没有分析逻辑。因此描述明显夸大了该代码块的实际能力,属于描述与行为不一致。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
86% confidence
Finding

代码的核心确实与微信公众号文章/公众号信息获取相关,和声明的大方向基本一致。但存在明显描述-行为不完全匹配:一方面,代码新增了主体信息与详细信息查询能力,这属于未在描述中体现的能力;另一方面,声明重点提到“爆款查询与分析”,而代码中仅有搜索、列表、下载和基础信息查询,没有任何爆款识别、统计分析、热度计算或分析输出逻辑。因此应判定为存在描述与实际行为的实质性不一致。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding

The declared description is specifically about WeChat public account article scraping/search and analysis. The actual code chunk only re-exports a generic trends toolkit interface for fetching trending data and processing/scoring/sorting/formatting articles. There is no evidence in this snippet of mp.weixin.qq.com-specific handling, public account search, or article list extraction. While '爆款查询与分析' loosely overlaps with trending article analysis, the primary behavior shown is broader and differently framed than the declared WeChat-focused purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

声明描述覆盖了多个能力:抓取微信公众号文章、搜索公众号、文章列表、爆款查询与分析。但提供的代码片段实际只实现了一个趋势数据获取函数:基于 keyword 和可选 start_date 调用第三方 API,并将返回数据整理为几个排行类别。它没有解析或抓取 mp.weixin.qq.com 链接内容,没有搜索公众号实体,也没有拉取某公众号的文章列表。虽然‘爆款查询与分析’与代码行为部分一致,但整体声明明显宽于实际功能,且触发场景强调的是微信公众号文章链接,而代码并未处理这类资源。因此应判定为描述与实际行为存在不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared purpose centers on WeChat public account article scraping, search, listing, and hot-article analysis. The actual code chunk is a generic formatter factory for trend results. It does not access mp.weixin.qq.com, fetch articles, search accounts, analyze article popularity, or use any WeChat-related resources. This is a materially different purpose from the description, so it should be flagged as a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

声明描述的是一个面向微信公众号内容抓取、搜索和分析的完整技能;而给定代码片段的实际作用只是结果展示层的文本输出组件,不包含网络抓取、公众号搜索、文章列表拉取或爆款分析计算逻辑。虽然它可能属于该技能的辅助模块,但就这段代码本身而言,其主要目的与声明的核心能力并不一致,因此应判定为描述与代码行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

描述强调的是微信公众号内容的抓取、搜索、列表获取以及爆款分析的整体能力;但提供的代码仅包含 trends/scoring.py 中的打分逻辑,没有任何网络请求、页面抓取、公众号搜索、文章列表拉取或 mp.weixin.qq.com 链接处理功能。虽然“爆款查询与分析”中的“分析”部分与文章评分有一定关联,但该代码片段的实际主功能是对已有文章数据进行打分,不足以覆盖声明中的主要能力。因此描述与该代码行为存在明显不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

该代码块是一个结果后处理模块:输入已有文章对象列表,对其按 photo_id 去重,调用外部评分函数打分,基于关键词匹配数量/相关性进行过滤,再做全局排序和分类多样性控制。它不访问微信页面、不解析 mp.weixin.qq.com、不执行抓取或搜索,也没有体现针对微信公众号生态的专用逻辑。声明描述的是一个上游数据获取与分析型技能,而实际代码只是下游排序策略组件,主用途与声明存在明显偏差。

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The document instructs users to export full authenticated WeChat platform cookies as JSON and send them to the agent, but it does not warn that these cookies are equivalent to live session credentials. Anyone with access to that data can potentially impersonate the user on mp.weixin.qq.com, access account data, and perform actions until the session expires.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Telling users to provide the full authenticated session export to the agent for storage is a direct secret-handling anti-pattern. In the context of a skill that operates on WeChat official platform data, the session material likely grants access to protected account functions and data, so centralizing it in agent-managed configuration materially raises account takeover and data exposure risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

Sending requests over a raw TLS socket with trust checks disabled creates an unsafe network transmission path with no assurance of peer identity. In the context of a skill that fetches article data from external services, this can expose queried URLs, parameters, and returned content to interception, modification, or spoofing without any user awareness.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs users to configure sensitive credentials such as a Cookie and MPTEXT_API_KEY but provides no warning about secure storage, least privilege, exposure risk, or account implications. In a skill that performs external fetching and fallback through third-party services, missing credential-handling guidance increases the risk of token leakage, account misuse, and accidental disclosure through logs or shared environments.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documented commands perform content fetching, downloading, searching, and statistics/trends analysis using curl, mptext, Cookie-based access, and external APIs, but the user is not warned that URLs, article text, keywords, account names, and possibly identifiers may be sent to third-party services. This creates a privacy and data-governance risk, especially when users analyze non-public, sensitive, or regulated content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The guide directs users to store API keys, cookies, and tokens in scripts/skill.env without any warning about local plaintext storage risks, file permissions, accidental commits, or log exposure. This increases the chance that sensitive credentials are leaked through source control, backups, shared machines, or other local compromise paths.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The document explicitly instructs use of API keys and Cookies as fallback mechanisms but does not warn that these credentials are sensitive, may grant access to account-scoped data, and can create privacy or account-abuse risks if mishandled. In this skill context, the omission is more dangerous because scraping WeChat content often relies on authenticated sessions, so users may be encouraged to supply live cookies without understanding exposure, storage, or revocation implications.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module is explicitly designed to bypass normal TLS/SNI behavior for anti-crawling circumvention, which exceeds the stated article-reading purpose and weakens transport security guarantees. By using a custom raw socket client to avoid standard HTTPS validation paths, the skill creates a covertive network capability that can contact remote services in a way that is harder to audit and more susceptible to interception or misuse.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The code disables both certificate verification and hostname checking before wrapping the socket, which defeats TLS server authentication entirely. This allows man-in-the-middle attackers, malicious proxies, or hostile networks to impersonate the remote server and tamper with responses returned to the skill.

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/core/utils.py (reported line 49)May include surrounding context.

python
"--max-time", "30",
                search_url
            ]
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=35)
            html = result.stdout

            if not html or len(html) < 500:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The function executes curl via subprocess.run, which performs an outbound HTTP request using the provided article title as query data. While the docstring describes the lookup behavior, there is no user-facing confirmation, logging, or warning in this code path that network access will occur and transmit the query externally.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
78% confidence
Finding

Reading WeChat articles obviously requires HTTP access, but it does not inherently require launching external system binaries. Using subprocess.run to execute curl expands the skill's capability from content retrieval into host-level process execution, which is materially broader than the manifest suggests.

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/fetch_wechat_article.py (reported line 162)May include surrounding context.

python
"-H", f"Referer: {strat['referer']}",
               "--connect-timeout", "15", "--max-time", "30", url]

        result = subprocess.run(cmd, capture_output=True, text=False)
        html_text = result.stdout.decode("utf-8", errors="replace")

        if len(html_text) < 1000:

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill sends user-supplied article URLs to an external paid service (mptext_api) as a fallback, but this data flow is not disclosed in the code path and exceeds a purely local fetch/extract expectation. Even if aligned with the broad feature goal of reading WeChat articles, it creates a third-party sharing/privacy boundary that can expose user activity, article targets, and possibly retrieved content to an external provider.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal, suspicious.insecure_tls_verification

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/skill.env:2

HTTPS certificate verification is disabled.

Warn
Code
suspicious.insecure_tls_verification
Location
scripts/core/http_client.py:115