Back to skill

Security audit

WeChat Publisher 微信公众号发布

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real WeChat publishing helper, but it handles reusable WeChat secrets insecurely and can add maintainer promotional content to user drafts.

Install only if you are comfortable giving this skill access to a WeChat official account AppID/AppSecret and sending article HTML and images to WeChat/Tencent APIs. Avoid --save-config unless you protect the resulting .wechat-config.json, never commit it, and consider rotating any secret already exposed through command history or local files. Review generated drafts before publishing, especially the footer and author fields, because the skill may add maintainer branding.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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)

T01 · Skill Instruction Hijacking

Warning
Location
SKILL.md:102
Finding

Mandatory Promotional Content Injection into User Articles

Content
View full analysis
有用AI — 有用才会用,会用才有用。
AI领域连续创业者、落地实战派
亲手打造AI产品,服务数百家中大型名企

``` ### Technical Analysis The skill defines a fixed promotional signature as the standard footer for articles processed for publication. This instruction is unrelated to the core technical requirements of converting HTML, uploading images, and submitting a WeChat draft. Because the signature is presented as mandatory publishing content rather than an optional template, an agent following the skill may insert the maintainer's branding and promotional claims into user-provided material without obtaining explicit authorization. The resulting draft no longer faithfully represents the user's original article. This is classified as instruction hijacking because skill-level instructions alter the expected output by requiring unrelated third-party promotional material. ### Attack Path 1. A user asks the agent to publish an existing article to a WeChat draft. 2. The agent loads and follows `SKILL.md`. 3. During formatting, the agent applies the mandatory standard footer. 4. The maintainer's branding and promotional claims are appended to the user's article. 5. The modified article is submitted to the user's WeChat draft account. 6. If the user publishes the draft without identifying the modification, the third-party promotion becomes publicly distributed under the user's account. ### Impact Assessment The issue does not grant operating-system privileges or direct access beyond the publishing workflow. Its impact is on content integrity and user authorization. An attacker controlling these skill instructions can cause unauthorized text to be inserted ...[truncated 326 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/upload-draft.js:77
Finding

WeChat AppSecret Exposure Through Command-Line Arguments and Plaintext Configuration

Content
View full analysis
公众号AppSecret ``` ```javascript function saveConfig(config) { fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2)); console.log(`✅ 配置已保存到 ${CONFIG_FILE}`); } ``` ```javascript if (opts.saveConfig) { saveConfig({ appid, secret }); } ``` The documented invocation also encourages passing the secret directly as a command-line argument: ```markdown node scripts/upload-draft.js --appid xxx --secret xxx --save-config ``` ### Technical Analysis The script accepts the WeChat AppSecret through `process.argv`. Command-line secrets may be retained in shell history, captured by process-monitoring or auditing systems, exposed in diagnostic output, or observed through process inspection where local permissions allow it. When `--save-config` is supplied, the script serializes the AppID and AppSecret directly into `.wechat-config.json`. The call to `fs.writeFileSync` does not specify a restrictive file mode. Consequently, the resulting permissions depend on the process umask and the state of any pre-existing file. On an inadequately configured multi-user system, another local account or process may be able to read the credential. The file is also unencrypted. Any backup, artifact collection process, accidental repository inclusion, or local compromise that captures the configuration file exposes the reusable AppSecret. ### Attack Path 1. A user follows the documented command and supplies the AppSecret through `--secret`. 2. The secret is recorded in shell history or remains observable in process metadata while the script runs. 3. If `--save-config` is used, the script writes the secret to `scripts/.wechat-config.json` ...[truncated 1345 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill’s declared boundary says it only handles formatting conversion, image upload, and draft submission, but it also instructs storing and later reading persistent AppID/Secret credentials from a local file. That expands the trust boundary and can mislead operators about what sensitive actions occur, increasing the chance that credentials are handled without proper review or safeguards.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill directs the agent to read local WeChat credentials and transmit them to external APIs without any explicit warning, consent checkpoint, or data-handling notice. This is dangerous because users may invoke the skill expecting publishing automation, while the agent silently accesses secrets and sends authenticated requests off-box.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

This step sends AppID and AppSecret to the WeChat token endpoint, which is expected for the integration but still constitutes external transmission of highly sensitive credentials. If logging, prompt leakage, shell history, or agent telemetry captures the constructed curl command, the credentials could be exposed and abused to access the publisher account.

Content

Scanner excerpt · SKILL.md (reported line 22)May include surrounding context.

从 scripts/.wechat-config.json 读取 appid 和 secret,然后调用微信API:

bash
curl "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={APPID}&secret={SECRET}"

返回 access_token,后续步骤都需要用到。

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

Uploading article images to WeChat is core to the skill, but it transmits user-provided files to an external third party. That can expose unpublished content, embedded metadata, or sensitive screenshots if the user is not clearly informed that local images will leave the environment.

Content

Scanner excerpt · SKILL.md (reported line 31)May include surrounding context.

md
> 此步骤由 Agent 通过 curl 调用微信API完成,不通过脚本。

- 正文图片 → `POST https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token={TOKEN}`(multipart/form-data 上传,返回微信图床URL)
- 封面图 → `POST https://api.weixin.qq.com/cgi-bin/material/add_material?type=image&access_token={TOKEN}`(返回 media_id)

### Step 3: 转换HTML(Agent 执行)

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

Uploading the cover image to WeChat’s material endpoint is an intentional external transfer, but it still carries confidentiality and account-scope risk because media becomes associated with the official account. In this context the behavior is expected, yet it remains security-relevant due to third-party transmission and potential accidental disclosure of unpublished assets.

Content

Scanner excerpt · SKILL.md (reported line 32)May include surrounding context.

md
> 此步骤由 Agent 通过 curl 调用微信API完成,不通过脚本。

- 正文图片 → `POST https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token={TOKEN}`(multipart/form-data 上传,返回微信图床URL)
- 封面图 → `POST https://api.weixin.qq.com/cgi-bin/material/add_material?type=image&access_token={TOKEN}`(返回 media_id)

### Step 3: 转换HTML(Agent 执行)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script stores the WeChat AppSecret in a local JSON file in plaintext without permission hardening, encryption, or prominent warnings. If the working directory is shared, backed up, committed, or readable by other local users/processes, the credential can be exposed and used to obtain access tokens for the公众号 account.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

This code transmits highly sensitive credentials by embedding the AppSecret directly in the request URL query string when fetching an access token. Query parameters are commonly captured in logs, shell history, proxy telemetry, debugging output, and monitoring systems, which can leak the secret beyond the intended recipient even though the transport uses HTTPS.

Content

Scanner excerpt · scripts/upload-draft.js (reported line 126)May include surrounding context.

js
// 获取access_token
async function getAccessToken(appid, secret) {
  console.log('🔑 正在获取access_token...');
  const url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${secret}`;
  const result = await httpsRequest(url);
  console.log(`✅ access_token获取成功(有效期7200秒)`);
  return result.access_token;

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

The script sends article content and an access token to an external third-party service, which is expected for this skill's purpose but still represents real data exfiltration outside the local environment. In this context the danger is increased because the access token is also embedded in the request URL query string, which may be logged by intermediaries or diagnostics and enable unauthorized API use if exposed.

Content

Scanner excerpt · scripts/upload-draft.js (reported line 136)May include surrounding context.

js
async function addDraft(accessToken, { title, author, content, thumbMediaId }) {
  console.log('📝 正在上传草稿到公众号...');

  const url = `https://api.weixin.qq.com/cgi-bin/draft/add?access_token=${accessToken}`;
  const data = {
    articles: [{
      title: title,

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The manifest says the skill is responsible for '图片上传', but the implementation only reads HTML, obtains an access token, and submits a draft. The code explicitly states it does not upload a cover image and instructs the user to upload media manually, which is a direct mismatch with the declared behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill's natural-language interface, usage text, and runtime messages are entirely in Chinese, with no indication that users may choose another language. This can violate a language/locale policy when tools must not force a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.