Back to skill

Security audit

公众号阅读增长榜

Security checks for vulnerabilities and agentic risk

Overview

The skill appears intended to fetch WeChat growth rankings, but it reads local shell profile files for API keys and can run on broad, ambiguous prompts, so users should review it before installing.

Install only if you are comfortable with the skill reading shell profile files to locate REDFOX_API_KEY and sending that key to redfox.hk for API access. Prefer setting the key in a scoped secret or temporary environment variable, review generated Markdown links before clicking, and use explicit WeChat ranking requests to avoid accidental activation.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/fetch_growth_rank.py:131
Finding

Unescaped Remote API Fields Permit Markdown Content and Link Injection

Content
View full analysis

Vulnerability Details

File Location: scripts/fetch_growth_rank.py:131-134, 193-199
Vulnerability Type: Markdown content and link injection
Risk Level: Medium

Technical Analysis

The script obtains article metadata from the remote RedFox API and interpolates it directly into a Markdown table without escaping Markdown control characters, removing line breaks, or validating the URL scheme.

The vulnerable link construction is:

python
def make_link(title: str, url: str) -> str:
    """生成Markdown链接"""
    t, u = safe_str(title), safe_str(url)
    return f'[{t}]({u})' if t != "-" and u != "-" else t

The resulting value, together with the remotely supplied account name and other fields, is inserted directly into the output table:

python
for rank_num, (acc, score) in enumerate(scored_data, 1):
    max_w = acc.get("maxWork") or {}
    user = safe_str(acc.get("userName"))

    lines.append(
        f"| {rank_num} | {user} | {make_link(max_w.get('title'), max_w.get('oriUrl'))} | "
        f"{format_count(max_w.get('watchCount'))} | {format_count(max_w.get('likeCount'))} | "
        f"{format_count(max_w.get('shareCount'))} | {safe_str(max_w.get('clicksCount'))} | "
        f"{safe_str(max_w.get('publicTime'))} | {score:.2f} |"
    )

Fields such as userName, maxWork.title, maxWork.oriUrl, and maxWork.publicTime originate in the external API response. Markdown metacharacters such as |, [, ], (, ), and embedded newlines are not neutralized. A crafted title can terminate the intended Markdown link or table cell and introduce additional links or rows. The URL is also accepted without restricting it to a safe scheme.

The exposure is reinforced by SKILL.md:123 and references/core_workflow.md:22-25, which require the assistant to reproduce the script's standard output verbatim. Consequently, the agent is instructed not to sanitize malformed or deceptive remote content ...[truncated 1541 chars]

Remediation
View remediation

Remediation Suggestions

  1. Escape Markdown metacharacters in every remotely supplied text field before inserting it into the table, including backslashes, pipes, brackets, parentheses, carriage returns, and newlines.
  2. Normalize multiline values to a single line so remote data cannot create additional rows or break table structure.
  3. Parse oriUrl with a standard URL parser and permit only expected schemes, preferably https.
  4. If the service has a defined set of legitimate article hosts, enforce an explicit hostname allowlist or visibly mark links to other hosts.
  5. Reject control characters and malformed URLs rather than rendering them.
  6. Keep raw API data separate from presentation data. The requirement to reproduce stdout verbatim should apply only after the script has safely encoded all external fields.
  7. Add regression tests using titles, account names, dates, and URLs containing pipes, newlines, brackets, nested links, and non-HTTPS schemes.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (12)

Tainted flow: 'headers' from os.getenv (line 96, credential/environment) → requests.get (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/fetch_growth_rank.py (reported line 101)May include surrounding context.

python
"X-API-KEY": api_key
    }
    try:
        resp = requests.get(API_URL, params={"rankDate": rank_date, "source": source},
                            headers=headers, timeout=30)
        resp.raise_for_status()
        return resp.json()

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

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

Content

Scanner excerpt · scripts/fetch_growth_rank.py (reported line 89)May include surrounding context.

python
return api_key

    # 第三级:提示用户配置
    raise ValueError(
        "缺少 API Key,请按以下步骤配置:\n"
        "1. 访问 https://redfox.hk/login?source=clawhub 注册账号\n"
        "2. 登录后在个人中心获取 API Key(格式:ak_xxxxxxxx)\n"
        "3. 设置环境变量:export REDFOX_API_KEY=<你的apikey>\n"
        "   或永久配置:echo 'export REDFOX_API_KEY=<你的apikey>' >> ~/.bashrc && source ~/.bashrc"
    )


def fetch_data(rank_date: str, source: str) -> dict:
    """调用API获取榜单数据"""
    api_key = get_api_key()
    headers = {
        "Content-Type": "application/json",
        "X-API-KEY": api_key
    }
    try:
        resp = requests.get(API_URL, params={"rankDate": rank_date, "source": source},
                            headers=headers, timeout=30)
        resp.raise_for_status()
        return resp.json()
    except Exception as e:
        raise Exception(f"API调用失败: {e}")


def safe_s

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The invocation phrase "WeChat growth rankings" / "latest growth chart" is broad enough that ordinary user requests about social-media trends or charts could unintentionally trigger this skill outside a clearly scoped context. Because the skill can call external ranking APIs and produce authoritative-looking output, accidental activation may lead to unintended data access, user confusion, or the model selecting this skill when another tool would be more appropriate.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README encourages invocation through very broad everyday phrases such as '公众号增长榜', '最新增长榜', and other natural-language requests. In an agent environment, overly generic triggers can cause accidental skill activation during normal conversation, leading the agent to call the skill unexpectedly and potentially transmit user queries or consume external API resources without clear user intent.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill documentation describes capabilities that require environment-variable access, file reads of shell configuration files, and outbound network access, but it does not declare any explicit tool scope or permission boundary. This increases the risk of over-privileged execution and makes sensitive operations like API key discovery from local shell profiles less transparent to users and host platforms.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The spec explicitly instructs the skill to read API credentials from users' shell configuration files (such as ~/.bashrc and ~/.zshrc), which is sensitive local-file access unrelated to simply displaying a leaderboard. Even if intended as a convenience fallback, this expands the skill's privileges to inspect local secrets and can expose credentials beyond the one needed for this API, especially if parsing is broad or implemented unsafely.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documentation normalizes reading credentials from local shell config files without clearly warning users that the skill would access sensitive files in their home directory. In this skill's context, which only needs to fetch remote ranking data, undisclosed local secret access is unnecessary and increases the chance of credential exposure or user surprise.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

L17-L18 将“用户输入不明确”直接映射为默认查询昨日增长榜,但没有说明哪些表述算“不明确”,也没有给出排除条件或要求先澄清用户意图。这种触发条件过于模糊,容易与日常含糊表达重叠,造成非预期调用。

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The example question "What accounts are on today's growth chart?" is too generic to reliably scope this skill to WeChat official-account rankings. In a multi-skill environment, such broad phrasing increases the chance of misrouting or unintended invocation, which can surface irrelevant external data and reduce trust in the assistant's behavior.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

L312 写明 REDFOX_API_KEY “仅通过环境变量读取”,但同一文件在 L091、L105 明确声明脚本还会回退读取 shell 配置文件。这属于文档对实际/声明行为的直接矛盾,会误导用户对凭据读取范围的理解。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code file contains natural-language strings that set the skill’s interface language to Chinese by default, beginning with the module docstring. Under the policy, language constraints should not be forced unless the user is given a choice or the locale limitation is clearly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The argparse description, help text, error messages, and status output are all presented only in Chinese. This creates a language/locale policy issue because the skill does not offer user opt-in or explain why a Chinese-only interface is required.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.