Back to skill

Security audit

wechat-claw-skill

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly does what it says, but it can publish to a real WeChat account and fetch/render user-supplied content with weak safeguards.

Install only if you are comfortable reviewing generated HTML before publication, using trusted article JSON and helper scripts, and approving every WeChat draft/publish action manually. Avoid feeding it untrusted source specs or internal URLs, and check rendered output for unexpected 39Claw attribution before connecting a real account.

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 (3)

T01 · Skill Instruction Hijacking

Warning
Location
templates/daily-intelligence.html:101
Finding

Hardcoded Publisher Branding Injected into Generated Articles

Content
View full analysis

THE DAILY INTELLIGENCE · AI 日报

{{SOURCE_COUNT}} 个顶级信息源 · 每日精选 · 自动生成

by 39Claw · {{DATE_SHORT}}

``` ```html

THE WEEKLY FINANCIAL REVIEW · 财经周报

全球视野 · 深度解读 · 每周精选

by 39Claw · {{DATE_SHORT}}

``` ```python # scripts/article_lib.py:92-101 def ensure_meta_defaults(article: dict[str, Any]) -> dict[str, Any]: raw_meta = article.get("meta") meta = raw_meta if isinstance(raw_meta, dict) else dict(raw_meta or {}) article["meta"] = meta parsed_date = parse_iso_date(meta.get("date")) weekdays = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"] meta.setdefault("date", parsed_date.isoformat()) meta.setdefault("author", "39Claw") ``` ``` ...[truncated 2034 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/collect_sources.py:115
Finding

Server-Side Request Forgery Through Unrestricted Source URL Fetching

Content
View full analysis
dict[str, Any]: request = Request(url, headers={"User-Agent": "Mozilla/5.0"}) with urlopen(request, timeout=timeout) as response: content_type = response.headers.get_content_type() body = response.read().decode("utf-8", errors="ignore") if content_type == "text/plain": text = " ".join(body.split()) title = "" else: parser = TextExtractor() parser.feed(re.sub(r"(?is)<(script|style).*?>.*?", " ", body)) title = parser.title text = " ".join(parser.chunks) return {"title": title, "content": text[:max_chars], "content_type": content_type} ``` The URL is ultimately obtained from an untrusted source entry: ```python elif entry_type == "url": payload = fetch_url(entry["url"], timeout, max_chars) payload.update({"type": "url", "label": label, "url": entry["url"]}) ``` ### Technical Analysis `fetch_url()` passes a caller-controlled URL directly to `urllib.request.urlopen()`. The implementation does not: - restrict the scheme to HTTP and HTTPS; - reject loopback, private, link-local, multicast, or reserved IP addresses; - block cloud metadata endpoints; - validate the destination after DNS resolution; - revalidate redirect targets; - enforce a destination-domain allowlist; or - cap the number of bytes read before decoding the response. A malicious source specification can therefore make the host running the skill request services that are not reachable by the attacker directly. Returned text is included in the normalized source bundle, creating a response-disclosure channel where the internal response is readable. Redirects and DNS resolution must be considered during remediation. Validating only the initial ...[truncated 1603 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/article_lib.py:49
Finding

Unsanitized HTML Injection in Rendered and Publishable Article Content

Content
View full analysis
str: text = "" if value is None else str(value).strip() if not allow_html: return html.escape(text) return text ``` ```python def render_body_paragraphs(value: Any, *, margin_bottom: str = "8px") -> str: paragraphs = normalize_paragraphs(value) if not paragraphs: return "" return "".join( f'

{normalize_text(paragraph, allow_html=True)}

' for paragraph in paragraphs ) ``` ```python def render_quote_block(block: dict[str, Any]) -> str: text = normalize_text(block.get("text") or "", allow_html=True) attribution = normalize_text(block.get("attribution") or "") return ( '
' '
' f'

{text}

' f'

{attribution}

' "
" ) ``` ```python rendered = apply_replacements( template_text, { "DATE_CN": normalize_text(meta.get("date_cn")), "DATE_SHORT": normalize_text(meta.get("date_short")), "SOURCE_COUNT": normalize_text(meta.get("source_count")), "NEWS_COUNT": normalize_text(meta.get("news_count")), "TITLE": normalize_text(meta.get("title")), "SUBTITLE": normalize_text(meta.get("subtitle") or ""), "AUTHOR": normalize_text(meta.get("author")), ...[truncated 3424 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (33)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The supplied code chunk only implements source ingestion and normalization. It reads local files, fetches web pages or plain text from URLs, accepts raw text and stdin, extracts text/title content, truncates content, and emits a JSON bundle. While this loosely fits the '信息搜集' portion of the description, it does not implement the declared end-to-end purpose of automated WeChat article writing and publishing, such as composing articles, formatting HTML, planning images, creating drafts, or publishing. The code’s primary purpose is materially narrower than the declared description, so this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description presents a complete automated WeChat article writing and publishing workflow, including content gathering, image planning, formatting, draft creation, and publishing. The supplied code chunk only implements a narrow subset: local rendering of article JSON into HTML with optional validation and file/stdout output. This partially aligns with the 'local rendering' and 'validation' portion of the description, but materially does not match the broader declared purpose of full automation and publishing. There are no undeclared dangerous capabilities visible; the mismatch is that the description significantly overstates what this code chunk actually does.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
nClaw 的 workspace skills 目录加载的,不要假设当前工作目录就是 skill 根目录。执行本仓库内置脚本、模板或参考文件时,优先先定位 `SKILL.md` 所在目录,再从该目录拼绝对路径访问 `scripts/`、`templates/`、`references/`。

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · templates/daily-intelligence.html (reported line 1)May include surrounding context.

html
<!--
  AI日报微信公众号模板 - THE DAILY INTELLIGENCE
  世界级报刊风格 v1.0

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · templates/daily-intelligence.html (reported line 1)May include surrounding context.

html
<!--
  AI日报微信公众号模板 - THE DAILY INTELLIGENCE
  世界级报刊风格 v1.0

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · templates/weekly-financial.html (reported line 1)May include surrounding context.

html
<!--
  财经周报微信公众号模板 - THE WEEKLY FINANCIAL REVIEW
  世界级报刊风格 v1.0

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · templates/weekly-financial.html (reported line 1)May include surrounding context.

html
<!--
  财经周报微信公众号模板 - THE WEEKLY FINANCIAL REVIEW
  世界级报刊风格 v1.0

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · README.md (reported line 71)May include surrounding context.

md
## Star History

[![Star History Chart](https://api.star-history.com/image?repos=th3ee9ine/wechat-claw-skill&type=date&legend=top-left)](https://www.star-history.com/?repos=th3ee9ine%2Fwechat-claw-skill&type=date&legend=top-left)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
79% confidence
Finding

The skill documentation instructs the agent to use shell, local file access, and network-accessing scripts, but the manifest does not declare any explicit tool scope such as permissions or allowed-tools. That creates a capability/visibility gap: reviewers and runtime policy layers cannot easily tell that the skill may read local files, write outputs, fetch remote URLs, and invoke external publishing helpers.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The quick-start instructions include a command path that can create drafts and publish to a WeChat account, but they do not prominently warn that this is a high-impact remote side effect affecting a real external account. In agentic environments, insufficient confirmation gates around publishing can cause unintended content publication or account changes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The publication step describes creating drafts and publishing, but does not clearly frame the action as a potentially irreversible external operation with user/account impact. Without strong risk signaling and confirmation requirements, an agent could execute publication prematurely, leading to accidental posting, content leakage, or reputational harm.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documentation describes a workflow that can generate images, upload assets, create drafts, and publish content, but it does not clearly warn users that these actions transmit data to external services and may result in live publication. In a skill designed for automated WeChat article production, omission of such warnings increases the risk of accidental publication, unintended disclosure of article content or local files, and unsafe execution of high-impact commands.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README explicitly documents a one-command flow that can generate images, upload assets, create drafts, and publish to a WeChat public account, but it does not prominently warn that these are real external side effects against a live account. In a skill intended for automation, that omission increases the risk of accidental publication or account content changes by users or upstream agents who may treat the example as safe to run.

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 · docs/openclaw.en.md (reported line 38)May include surrounding context.

Using a symlink keeps updates simple:

bash
mkdir -p ~/.openclaw/workspace/skills
ln -sfn /abs/path/to/wechat-claw ~/.openclaw/workspace/skills/wechat-claw

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document shows a full publishing command using --create-draft and --publish but does not clearly warn that these flags can create real drafts and push live content to a production WeChat account. In a skill focused on automated article generation and publishing, omission of an explicit safety warning increases the chance of accidental publication, especially when users copy-paste commands verbatim.

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 · docs/openclaw.zh.md (reported line 38)May include surrounding context.

推荐用软链,更新仓库时不需要重复复制:

bash
mkdir -p ~/.openclaw/workspace/skills
ln -sfn /abs/path/to/wechat-claw ~/.openclaw/workspace/skills/wechat-claw

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 · docs/openclaw.zh.md (reported line 38)May include surrounding context.

推荐用软链,更新仓库时不需要重复复制:

bash
mkdir -p ~/.openclaw/workspace/skills
ln -sfn /abs/path/to/wechat-claw ~/.openclaw/workspace/skills/wechat-claw

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The documentation shows a full publishing flow using --create-draft and --publish but does not include an explicit warning that these actions can create or publicly publish content on a real WeChat account. In an agent-skill context, that omission is risky because users or downstream agents may execute the command assuming it is a local-only workflow, leading to unintended public-facing actions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The file consistently prescribes Chinese text for covers and captions, such as 'AI日报', '财经周报', '科技周报', and the fixed caption '图片说明 | AI 生成'. There is no indication that users may choose another language or locale, which makes this a natural-language locale policy concern under the rule.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This markdown file presents all guidance, constraints, and examples exclusively in Chinese. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly documented and justified, which is not present here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file is natural-language guidance and repeatedly assumes a fixed Chinese-language, WeChat-publication context, beginning with a Chinese-only title and platform-specific instructions. Because the file does not offer any language or locale opt-in or explain that the skill is restricted to Chinese/WeChat use, it can violate the policy against forcing a specific language or locale without user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code unconditionally formats dates using Chinese weekday names and Chinese date strings in date_cn, which imposes a specific language/locale choice. This is a natural-language policy concern because the skill does not offer a user language choice or document that it is intentionally region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The missing-source error message and several CLI help strings include Chinese-language instructions, which imposes a locale choice in user-facing text without offering an explicit language preference or opt-in. This can violate language/locale policy when the skill is otherwise not documented as region-specific.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The code performs outbound HTTP requests for each url source via urlopen, which can disclose system IP/addressing metadata and transmit user-specified request targets. There is no confirmation prompt, runtime notice, or comment/docstring warning users that remote network access will occur when URL sources are provided.

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

python
def _run(cmd: list[str]) -> str:
    result = subprocess.run(cmd, check=True, capture_output=True, text=True)
    return result.stdout.strip() or result.stderr.strip()

Static analysis

No suspicious patterns detected.