Back to skill

Security audit

WeChat Official Account Draft Management

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a real WeChat draft-management tool, but it handles account credentials and can publish or delete content with weak local secret-storage and confirmation guidance.

Install only if you are comfortable giving the tool WeChat Official Account API authority to upload media, read drafts, create drafts, submit publications, and delete drafts. Avoid putting the AppSecret in ~/.zshrc; use a dedicated secret manager or tightly permissioned local environment file, and harden or disable the token cache if possible. Treat publish and delete commands as irreversible account actions and confirm the target media_id before use.

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

Warning
Location
SKILL.md:34
Finding

WeChat AppSecret Persisted in a Shell Startup File

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/channel.py:64
Finding

WeChat Bearer Access Token Cached Without Explicit Permission Hardening

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (35)

Tainted flow: 'req' from os.getenv (line 432, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/channel.py (reported line 57)May include surrounding context.

python
try:
        req = urllib.request.Request(url)
        with urllib.request.urlopen(req, timeout=30) as response:
            data = json.loads(response.read().decode('utf-8'))
            
            if 'access_token' in data:

Tainted flow: 'req' from os.getenv (line 432, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/channel.py (reported line 296)May include surrounding context.

python
try:
        req = urllib.request.Request(url)
        with urllib.request.urlopen(req, timeout=30) as response:
            data = json.loads(response.read().decode('utf-8'))
            
            if 'access_token' in data:

Tainted flow: 'req' from os.getenv (line 432, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/channel.py (reported line 387)May include surrounding context.

python
try:
        req = urllib.request.Request(url)
        with urllib.request.urlopen(req, timeout=30) as response:
            data = json.loads(response.read().decode('utf-8'))
            
            if 'access_token' in data:

Tainted flow: 'req' from os.getenv (line 432, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/channel.py (reported line 411)May include surrounding context.

python
try:
        req = urllib.request.Request(url)
        with urllib.request.urlopen(req, timeout=30) as response:
            data = json.loads(response.read().decode('utf-8'))
            
            if 'access_token' in data:

Tainted flow: 'req' from os.getenv (line 432, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/channel.py (reported line 436)May include surrounding context.

python
try:
        req = urllib.request.Request(url)
        with urllib.request.urlopen(req, timeout=30) as response:
            data = json.loads(response.read().decode('utf-8'))
            
            if 'access_token' in data:

Tainted flow: 'req' from os.getenv (line 432, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/channel.py (reported line 119)May include surrounding context.

python
'Content-Length': len(data)
        })
        
        with urllib.request.urlopen(req, timeout=60) as response:
            result = json.loads(response.read().decode('utf-8'))
            
            if 'url' in result:

Tainted flow: 'req' from os.getenv (line 432, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/channel.py (reported line 358)May include surrounding context.

python
'Content-Length': len(data)
        })
        
        with urllib.request.urlopen(req, timeout=60) as response:
            result = json.loads(response.read().decode('utf-8'))
            
            if 'url' in result:

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The documented purpose understates actual behavior by omitting automatic cover generation, temporary file creation, use of the external sips utility, and comment-control settings. Description/behavior mismatches are dangerous because users and policy systems may authorize the skill under false assumptions, while the hidden behaviors expand local execution and content-modification surface.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/wechat_api.md (reported line 7)May include surrounding context.

认证

获取 Access Token

text
GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/wechat_api.md (reported line 246)May include surrounding context.

认证

获取 Access Token

text
GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
os.makedirs(CONFIG_DIR, exist_ok=True)

def get_access_token() -> Optional[str]:
    """获取 Access Token"""
    appid = os.getenv('WECHAT_APPID')
    appsecret = os.getenv('WECHAT_APPSECRET')

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/channel.py (reported line 30)May include surrounding context.

python
os.makedirs(CONFIG_DIR, exist_ok=True)

def get_access_token() -> Optional[str]:
    """获取 Access Token"""
    appid = os.getenv('WECHAT_APPID')
    appsecret = os.getenv('WECHAT_APPSECRET')

Credential Access

High
Category
Privilege Escalation
Confidence
83% confidence
Finding

The script caches the retrieved access token under ~/.config/channel/access_token.json without setting restrictive file permissions or validating the directory/file mode. On multi-user systems or misconfigured environments, another local user or process may read the token and act on the associated WeChat account until expiry.

Content

Scanner excerpt · scripts/channel.py (reported line 74)May include surrounding context.

python
return token
            else:
                print(f"❌ 获取 Access Token 失败: {data.get('errmsg', 'Unknown error')}")
                return None
                
    except Exception as e:

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/channel.py (reported line 564)May include surrounding context.

python
parser.print_help()
        return
    
    # 获取 access token
    access_token = get_access_token()
    if not access_token:
        return

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill declares access to secrets and describes file, shell, and network-backed behavior, but it does not define any explicit tool scope or permission boundaries. In an agent setting, this can lead to over-broad execution authority, making accidental secret exposure, unintended file access, or unsafe command execution more likely if the implementation is invoked with excessive privileges.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

md
---
name: channel
description: WeChat Official Account Draft Box management tool. Create and manage graphic draft articles via WeChat API, supporting text and images. Automatically extracts the first paragraph as summary. Supports draft creation, listing, publishing, and deletion.
env:
  - WECHAT_APPID
  - WECHAT_APPSECRET

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill exposes a destructive delete operation without warning that it permanently removes drafts or recommending confirmation before use. In automation contexts, this increases the chance of irreversible content loss from operator error, prompt injection, or misuse by downstream workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The deletion endpoint is documented as a normal operation without any warning that it permanently removes draft content. In a content-management skill, undocumented destructive actions increase the risk of accidental data loss, especially if an agent or user invokes the endpoint without confirmation safeguards.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The document instructs users to upload local image files to WeChat using multipart/form-data but does not clearly warn that the file contents are transmitted to a third-party external service. In a skill that manages WeChat drafts and media, this omission can lead to inadvertent disclosure of sensitive local images or embedded metadata.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/wechat_api.md (reported line 279)May include surrounding context.

}] }

text
response = requests.post(url, json=data)
return response.json()
text

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/wechat_api.md (reported line 10)May include surrounding context.

md
from typing import List, Dict, Optional

# 微信 API 配置
WECHAT_API_BASE = "https://api.weixin.qq.com/cgi-bin"

# 存储文件
CONFIG_DIR = os.path.expanduser("~/.config/channel")

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/wechat_api.md (reported line 31)May include surrounding context.

md
from typing import List, Dict, Optional

# 微信 API 配置
WECHAT_API_BASE = "https://api.weixin.qq.com/cgi-bin"

# 存储文件
CONFIG_DIR = os.path.expanduser("~/.config/channel")

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/wechat_api.md (reported line 77)May include surrounding context.

md
from typing import List, Dict, Optional

# 微信 API 配置
WECHAT_API_BASE = "https://api.weixin.qq.com/cgi-bin"

# 存储文件
CONFIG_DIR = os.path.expanduser("~/.config/channel")

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/wechat_api.md (reported line 132)May include surrounding context.

md
from typing import List, Dict, Optional

# 微信 API 配置
WECHAT_API_BASE = "https://api.weixin.qq.com/cgi-bin"

# 存储文件
CONFIG_DIR = os.path.expanduser("~/.config/channel")

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/wechat_api.md (reported line 145)May include surrounding context.

md
from typing import List, Dict, Optional

# 微信 API 配置
WECHAT_API_BASE = "https://api.weixin.qq.com/cgi-bin"

# 存储文件
CONFIG_DIR = os.path.expanduser("~/.config/channel")

Static analysis

No suspicious patterns detected.