Back to skill

Security audit

微信公众号发布工具

Security checks for vulnerabilities and agentic risk

Overview

This WeChat publishing skill is mostly coherent, but it needs review because its helper script can execute shell code through unsafe command construction and shared credential-file loading.

Review this skill before installing. Use it only with non-sensitive article drafts unless you are comfortable sending content to WeChat and any configured AI provider. Avoid the shell wrapper until eval and direct .env sourcing are fixed; prefer the Python CLI with explicit commands. Pin the install to a trusted release or commit, protect ~/.wechat-publish-pro/config.yaml with owner-only permissions, and use narrowly scoped WeChat and AI credentials.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/publish.sh:178
Finding

Shell Command Injection Through Dynamically Constructed eval Command

Content
View full analysis
/tmp/wechat-publisher-pwned; #' ``` 3. The script appends this value to `publish_cmd`. 4. `eval` reparses the resulting command string as shell program text. 5. The injected command executes with the same operating-system privileges as the user running the publishing script. The same issue can arise w ...[truncated 882 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/publish.sh:96
Finding

Arbitrary Shell Code Execution by Sourcing a Shared Credential File

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
src/wechat_publisher/config.py:14
Finding

Overbroad Automatic Reading of the Shared OpenClaw Secret Store

Content
View full analysis
bool: """检测是否在 openclaw 环境中运行""" openclaw_dir = Path.home() / ".openclaw" return openclaw_dir.exists() and openclaw_dir.is_dir() def load_openclaw_env() -> dict[str, str]: """从 ~/.openclaw/.env 加载环境变量""" env_file = Path.home() / ".openclaw" / ".env" env_vars = {} if env_file.exists(): with open(env_file, encoding="utf-8") as f: for line in f: line = line.strip() if line and not line.startswith("#"): if "=" in line: key, value = line.split("=", 1) env_vars[key.strip()] = value.strip() return env_vars ``` The resulting dictionary is loaded automatically in `Settings.load()` and queried for WeChat and AI settings. ### Technical Analysis The implementation opens and parses every assignment in the shared `~/.openclaw/.env` file whenever OpenClaw's home directory exists. It does so even though the publisher needs only a small set of named WeChat and AI configuration values. Unlike the shell script's `source` behavior, this Python parser does not execute the file as shell code. However, it still reads all unrelated credentials into the publisher process's memory. The mere existence of `~/.openclaw` is treated as authorization to inspect the shared secret file; there is no explicit user opt-in, per-command need check, or allowlisted parsing at the file-reading boundary. The reviewed code only uses selected keys and no confirmed exfiltration of unrelated credentials was found. Nevertheless, reading all secrets increases the consequences of process inspection, crash reporting, debugging, dependency compromise, or a future vulnerability. ### Attack Path 1. A u ...[truncated 1277 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/wechat_publisher/config.py:128
Finding

Plaintext Credential Storage Without Enforced Restrictive Permissions

Content
View full analysis
None: """保存配置到文件""" self.config_dir.mkdir(parents=True, exist_ok=True) config_file = self.get_config_file() data = { "accounts": {k: v.model_dump() for k, v in self.wechat.accounts.items()}, "default_account": self.wechat.default_account, "ai": self.ai.model_dump(), } with open(config_file, "w", encoding="utf-8") as f: yaml.dump(data, f, allow_unicode=True, default_flow_style=False) ``` ### Technical Analysis The serialized configuration contains complete WeChat account secrets and the AI provider API key. The code writes this data as plaintext YAML but does not explicitly enforce owner-only permissions on either the directory or the file. For a newly created file, effective permissions depend on the process umask. If the file already exists with permissive permissions, opening it with mode `"w"` truncates and rewrites it without correcting those permissions. The directory creation also relies on default permission behavior. This creates a local credential disclosure risk in multi-user systems, shared home directories, container volume mounts, backups, or environments with an unexpectedly permissive umask. ### Attack Path 1. The publisher runs under a permissive umask, or `config.yaml` already exists with group- or world-readable permissions. 2. A user invokes `config init`, `config add-account`, or `config set`, causing `settings.save()` to run. 3. The method writes WeChat AppSecrets and AI API keys to `~/.wechat-publish-pro/config.yaml`. 4. Because restrictive permissions are not enforced, another local account or process with filesystem access reads the file. 5. The exposed credentials are then used directly against the corresponding external APIs. No hardcoded pr ...[truncated 685 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (48)

YARA rule 'agent_skill_remote_bootstrap_execution': Remote script or code download followed by execution/bootstrap installation [agent_skills]

High
Category
YARA Match
Confidence
85% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · README.md (reported line 8)May include surrounding context.

wechat-publish-pro

把文章发到微信公众号草稿箱,发布前自动 AI 去痕,让内容读起来更像真人写的。

装上

bash
pip install git+https://github.com/yuesf/wechat-publish-pro.git

配一下

第一步:获取微信公众号凭证

  1. 登录 https://developers.weixin.qq.com/ 公众号平台
  2. 获取 AppID 和 AppSecret

第二步:配置凭证

bash
# 初始化
wechat-publish-pro config init

# 微信公众号的凭证
wechat-publish-pro config set wechat.app_id <你的AppID>
wechat-publish-pro config set wechat.app_secret <你的AppSecret>

# AI 去痕用的 API(可选,但建议配)
wechat-publish-pro config set ai.api_key <你的API K

YARA rule 'agent_skill_remote_bootstrap_execution': Remote script or code download followed by execution/bootstrap installation [agent_skills]

High
Category
YARA Match
Confidence
91% confidence
Finding

The installation instruction uses 'pip install git+https://...', which directs users to install code directly from a remote Git repository rather than from a vetted, pinned package source. In this skill context, that is risky because users are asked to install code that will handle publication credentials and interact with external services, so a repository compromise, tag drift, or supply-chain attack could lead to credential theft or arbitrary code execution on the host.

Content

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

封面生成*: 自动处理封面图,支持本地/网络图片

  • 直接发布: 一键发布到微信公众号草稿箱

触发条件

当用户需要以下操作时自动触发:

  • 将 Markdown 或 HTML 文章发布到微信公众号草稿箱
  • 转换 Markdown 为公众号格式 HTML
  • 使用特定主题发布公众号文章
  • 测试微信连接

安装

bash
# 从 GitHub 安装
pip install git+https://github.com/yuesf/wechat-publish-pro.git

配置

第一步:获取微信公众号凭证

  1. 登录 https://developers.weixin.qq.com/ 公众号平台
  2. 获取 AppID 和 AppSecret

第二步:配置凭证

配置文件(多账号支持)

配置文件路径:~/.wechat-publish-pro/config.yaml

yaml
accounts:
  # 账号1(设为默认)
  default:
    name: 技术公众号
    app_id: wx89c409208d11dc5b
    app_secret: your_app_secret_here
  # 账号2
  health:
    name: 养生公众号
    app_id

Credential Access

High
Category
Privilege Escalation
Confidence
89% confidence
Finding

The credential access concern is substantiated because the script reads a predictable secrets file and imports its contents into the environment for downstream use. Combined with direct sourcing, this increases the blast radius of any compromise of $HOME/.openclaw/.env by enabling both secret exposure and arbitrary shell execution in the user's context.

Content

Scanner excerpt · scripts/publish.sh (reported line 97)May include surrounding context.

sh
# 加载环境变量
load_env() {
    local env_file="$HOME/.openclaw/.env"
    if [[ -f "$env_file" ]]; then
        log_info "从 $env_file 加载环境变量"
        set -a

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · src/wechat_publisher/config.py (reported line 21)May include surrounding context.

python
def load_openclaw_env() -> dict[str, str]:
    """从 ~/.openclaw/.env 加载环境变量"""
    env_file = Path.home() / ".openclaw" / ".env"
    env_vars = {}
    if env_file.exists():

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · src/wechat_publisher/config.py (reported line 78)May include surrounding context.

python
def load_openclaw_env() -> dict[str, str]:
    """从 ~/.openclaw/.env 加载环境变量"""
    env_file = Path.home() / ".openclaw" / ".env"
    env_vars = {}
    if env_file.exists():

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · src/wechat_publisher/config.py (reported line 22)May include surrounding context.

python
def load_openclaw_env() -> dict[str, str]:
    """从 ~/.openclaw/.env 加载环境变量"""
    env_file = Path.home() / ".openclaw" / ".env"
    env_vars = {}
    if env_file.exists():
        with open(env_file, encoding="utf-8") as f:

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · src/wechat_publisher/converter/css_theme.py (reported line 47)May include surrounding context.

python
if properties:
            rules.append(CSSRule(selector=selector, properties=properties))

    return rules


def css_to_inline_style(rules: list[CSSRule]) -> Dict[str, str]:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README states that articles are sent to a WeChat public account draft box and may be processed by an AI provider for “humanization,” but it does not clearly warn users that article content and credentials-associated operations involve third-party services. This omission increases the risk of users unknowingly transmitting sensitive or proprietary content to external AI APIs and the WeChat platform.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README suggests trigger phrases like “把这篇文章发到公众号” and “帮我发布到微信,测试一下,” which are broad natural-language requests that overlap with normal conversation. In an agent setting, this can cause unintended invocation and accidental publication of user content to WeChat, especially when paired with configured credentials and optional AI-based rewriting.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrases are broad enough to activate on ordinary conversational requests such as '帮我发布到微信' or '测试一下', which can cause the skill to engage without an explicit, informed confirmation step. In this skill's context, activation can lead to external publication workflows involving article content, images, and account credentials, so accidental invocation materially increases the risk of unintended data transmission or publication.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation describes publishing, cover handling, AI 'humanization,' and image upload, but does not clearly warn users that article text, images, and possibly credentials or API-derived content may be transmitted to external services including WeChat and optional AI providers. In an agent skill, this omission is dangerous because users may trigger the workflow expecting local formatting only, without understanding that sensitive content leaves the local environment.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The comment at L005 says the implementation is completely independent and does not depend on any external CLI tools. In practice, the script checks for and invokes external programs including python3 and wechat-publisher (L082-L089, L177-L193), so the documentation actively contradicts the actual behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The script sources $HOME/.openclaw/.env directly into the current shell, which executes any shell syntax in that file rather than just parsing key-value pairs. If the .env file is modified by another local process, attacker, or unsafe tooling, arbitrary commands could run with the user's privileges and sensitive credentials are loaded into the publishing process without validation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The script constructs and executes a publish command for wechat-publisher, and its options and environment variables indicate use of WeChat and an AI provider. Although it logs the command being executed, there is no explicit warning in the script help or comments that article content and related metadata may be sent to remote services, which is the kind of user disclosure required for network transmission of user data.

Content

No source excerpt is available for this finding.

Ssd 2

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The feature is explicitly framed as '去痕处理' to make AI-generated content appear more natural and less detectable, which is an evasion-oriented use case rather than ordinary proofreading. While not a direct exploit against the host system, this increases abuse potential by helping users conceal automated authorship and may facilitate policy evasion or deceptive content workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The code sends extracted article text to an external AI provider using configured API credentials, but the publish flow does not provide a clear, explicit warning that article contents will leave the local environment. In a publishing tool, articles may contain embargoed, proprietary, or sensitive draft material, so silent transmission to third-party services creates a real confidentiality risk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

The file is documented and structured as a WeChat multi-account configuration manager, but it also loads and stores separate AI provider settings and credentials. With no manifest declaring broader AI functionality, this adds a capability unrelated to the evident purpose of managing WeChat publishing accounts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The save() method serializes WeChat app secrets and AI API keys directly into ~/.wechat-publish-pro/config.yaml without any permission hardening, encryption, or explicit user warning. If the host is multi-user, backups are exposed, or file permissions are too broad, these long-lived credentials can be recovered and abused.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
86% confidence
Finding

The hardcoded external API endpoint indicates that content may be transmitted to a third-party service during normal operation. In this skill context, the converter processes arbitrary Markdown that may contain confidential text, so a built-in remote endpoint increases the risk of unintentional data disclosure, especially because remote use is supported directly in the conversion flow.

Content

Scanner excerpt · src/wechat_publisher/converter/__init__.py (reported line 41)May include surrounding context.

python
"""Markdown 转换器"""

    # mdnice API 端点
    MDNICE_API = "https://api.mdnice.com/api/v1/markdown"

    def __init__(self, options: Optional[ConvertOptions] = None) -> None:
        self.options = options or ConvertOptions()

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

When use_api is enabled, the full Markdown content is sent to an external or user-supplied HTTP endpoint for conversion. This can expose sensitive draft content, embedded secrets, or unpublished material without any consent flow, allowlist, or disclosure in this code path, which is a real data exfiltration/privacy risk in a publishing tool.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The function will fetch remote CSS from any supplied http/https URL without restriction, warning, or trust boundary enforcement. If untrusted input can control css_path, this can enable SSRF-like outbound requests, unexpected network access, privacy leakage, and consumption of attacker-controlled content that is later transformed into inline styles.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The docstring says the code is already HTML-escaped and specifically mentions < -> &lt;, > -> &gt;, then the implementation performs string highlighting based on &quot; and &#39; patterns. However, _render_code_block only escapes &, <, and >, not single or double quotes, so the documented premise for quote-safe highlighting is false and the quote-highlighting logic does not match actual behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

Natural-language strings throughout the module, including the module description and model prompts, are written exclusively in Chinese. The file does not indicate that the skill is intentionally China/Chinese-specific or provide any user opt-in or language selection, which can violate language/locale policy requirements.

Content

No source excerpt is available for this finding.

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 · src/wechat_publisher/humanizer/__init__.py (reported line 50)May include surrounding context.

python
PROVIDER_CONFIG = {
    Provider.OPENAI: {
        "name": "OpenAI",
        "base_url": "https://api.openai.com/v1",
        "default_model": "gpt-4",
    },
    Provider.QWEN: {

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 · src/wechat_publisher/humanizer/__init__.py (reported line 65)May include surrounding context.

python
},
    Provider.MINIMAX: {
        "name": "MiniMax",
        "base_url": "https://api.minimax.chat/v1",
        "default_model": "MiniMax-Text-01",
    },
    Provider.MOONSHOT: {

Static analysis

No suspicious patterns detected.