Back to skill

Security audit

AI公众号信息源

Security checks across malware telemetry and agentic risk

Overview

This skill is a real AI WeChat report generator, but its subscription and local search features create persistent, credential-backed behavior that needs careful review before installation.

Review before installing, especially if you plan to use --subscribe. Prefer an environment variable or short-lived key over the plaintext config file, avoid subscription unless you accept a recurring local job, and revoke or rotate the RedFox API key if you later remove the skill. Keep the generated reports private because they contain fetched third-party content and run browser JavaScript for search.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (31)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
script_path = os.path.abspath(__file__)
        cron_line = f"0 9 * * * /usr/bin/python3 {script_path} --no-open"
        try:
            subprocess.run(
                f'(crontab -l 2>/dev/null; echo "{cron_line}") | crontab -',
                shell=True, check=True, capture_output=True
            )
Confidence
97% confidence
Finding
This code builds a shell command with interpolated script_path and executes it with shell=True when installing a crontab entry. If the path contains shell metacharacters or quotes, it can break command boundaries and lead to command injection under the current user.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
else:
        script_path = os.path.abspath(__file__)
        try:
            subprocess.run(
                f'crontab -l 2>/dev/null | grep -v "{script_path}" | crontab -',
                shell=True, check=True, capture_output=True
            )
Confidence
98% confidence
Finding
This crontab removal command interpolates script_path into a shell pipeline using shell=True. A crafted path containing quotes or shell syntax could alter the grep command or inject additional commands, causing arbitrary command execution as the user.

Lp3

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding
The skill instructs users to run a Python script that accesses environment variables, reads and writes local files, uses the network, and invokes shell-style commands, yet it declares no permissions or explicit capability warnings. This creates a transparency and consent problem: users may execute a skill with broader local and network effects than the metadata suggests, including browser opening, local persistence, and API-backed network access.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
The skill installs persistent launchd/crontab jobs to keep running daily, which exceeds one-shot report generation and creates ongoing execution on the host. In this context, persistence increases attack surface and trust requirements, especially because it also ties into API-key handling and unattended network activity.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The skill starts a local HTTP server and exposes an API proxy that uses the user's API key for live searches, which goes beyond static report generation. Even though it binds to 127.0.0.1, it expands the runtime exposure surface and enables browser-accessible use of the credential-backed proxy.

Vague Triggers

Medium
Confidence
82% confidence
Finding
The instruction to 'Describe your needs in natural language' is overly broad and encourages unconstrained invocation based on free-form user requests. In a skill that can fetch external content, generate reports, search historical data, and install cron-based subscriptions, broad triggering increases the chance of unintended activation or execution of higher-impact actions from ambiguous phrasing.

Vague Triggers

Medium
Confidence
88% confidence
Finding
The README says to 'directly use natural language to describe needs,' which is very broad and provides little boundary on when the skill should activate. In an agent environment, overly permissive activation language can cause the skill to trigger on loosely related user requests, increasing the chance of unnecessary external data access, report generation, or scheduled-task actions without clear user intent.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The example trigger phrases are phrased as common conversational requests such as '今天 AI 圈有什么热点?' and '最近 AI 公众号什么选题火?', which may overlap with ordinary chat or general research queries. In an agentic system, this can lead to accidental invocation of the skill when the user did not specifically intend to use this data source or authorize its behaviors, especially if the skill can install subscriptions or generate local files.

Missing User Warnings

Low
Confidence
91% confidence
Finding
The skill does not clearly warn up front that running it writes HTML reports to a local directory and automatically opens them in the user's browser. While this is not inherently malicious, hidden side effects reduce informed consent and can surprise users in sensitive environments where file creation or browser launch is undesirable.

Missing User Warnings

Low
Confidence
90% confidence
Finding
The subscription feature enables recurring local report generation, but the skill text does not present this as a strong warning before users invoke it. Automatic recurring tasks can consume disk space, generate persistent artifacts, and continue operating beyond the user's immediate session if not fully understood.

Missing User Warnings

High
Confidence
99% confidence
Finding
The generated HTML embeds the API key directly into the report content, which can leak the credential to anyone with file access and to browser-executed scripts or copied reports. In this skill, that is especially dangerous because reports are saved to a user-accessible Downloads location and then opened in a browser.

Missing User Warnings

High
Confidence
98% confidence
Finding
The subscription installer writes the API key into the LaunchAgent plist environment, persisting the secret on disk without strong disclosure or protection. Any local process or user with access to that file may recover the key, and the secret remains available for unattended future runs.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
# 传递 API Key 环境变量
        env_section = ""
        api_key = os.environ.get(ENV_KEY)
        if api_key:
            env_section = f"""
        <key>EnvironmentVariables</key>
Confidence
95% confidence
Finding
This reads the API key from the environment specifically to persist it into a LaunchAgent plist, converting a relatively safe transient secret source into plaintext on-disk storage. That materially increases the chance of credential compromise during routine system use.

Unvalidated Output Injection

High
Category
Output Handling
Content
else:
        script_path = os.path.abspath(__file__)
        try:
            subprocess.run(
                f'crontab -l 2>/dev/null | grep -v "{script_path}" | crontab -',
                shell=True, check=True, capture_output=True
            )
Confidence
98% confidence
Finding
Unvalidated script_path data is inserted into a shell command that edits crontab contents. Because the value is not escaped safely, an attacker who controls the installation path can inject shell syntax or corrupt the filtering logic, leading to command execution or unintended cron modifications.

Session Persistence

Medium
Category
Rogue Agent
Content
export REDFOX_API_KEY=ak_你的密钥

# 方式二:配置文件
mkdir -p ~/.qoder/apis
echo '{"api_key":"ak_你的密钥"}' > ~/.qoder/apis/redfox.json

# 然后运行
Confidence
88% confidence
Finding
The skill recommends storing the API key in a persistent plaintext JSON file under ~/.qoder/apis/redfox.json. Persisting long-lived secrets on disk increases exposure to local compromise, accidental disclosure, backup leakage, or reuse by other processes, especially if file permissions are not restricted.

Session Persistence

Medium
Category
Rogue Agent
Content
cron_line = f"0 9 * * * /usr/bin/python3 {script_path} --no-open"
        try:
            subprocess.run(
                f'(crontab -l 2>/dev/null; echo "{cron_line}") | crontab -',
                shell=True, check=True, capture_output=True
            )
            info("订阅成功! 每天 09:00 自动生成爆款日报 (crontab)")
Confidence
94% confidence
Finding
Installing a crontab entry creates persistent unattended execution on the host. In the context of a content-report skill, that persistence is broader than necessary and compounds the risk of later code changes, credential misuse, or unnoticed background activity.

Session Persistence

Medium
Category
Rogue Agent
Content
def install_subscription():
    """安装定时任务,每天自动生成日报"""
    if sys.platform == "darwin":
        PLIST_DIR.mkdir(parents=True, exist_ok=True)
        plist_path = PLIST_DIR / f"{PLIST_LABEL}.plist"

        script_path = os.path.abspath(__file__)
Confidence
95% confidence
Finding
This function implements scheduled persistence for the skill, causing recurring execution without requiring the user to rerun it manually. For a daily report generator, that is broader-than-necessary system modification and increases the blast radius of any future bug or credential leak.

Session Persistence

Medium
Category
Rogue Agent
Content
"""安装定时任务,每天自动生成日报"""
    if sys.platform == "darwin":
        PLIST_DIR.mkdir(parents=True, exist_ok=True)
        plist_path = PLIST_DIR / f"{PLIST_LABEL}.plist"

        script_path = os.path.abspath(__file__)
        log_path = str(Path.home() / "Library" / "Logs" / "qoder-ai-hot-articles.log")
Confidence
95% confidence
Finding
Creating and using a plist path under LaunchAgents is part of establishing persistence on macOS. This modifies the user's environment in a durable way beyond the core one-time report-generation purpose.

Session Persistence

Medium
Category
Rogue Agent
Content
"""安装定时任务,每天自动生成日报"""
    if sys.platform == "darwin":
        PLIST_DIR.mkdir(parents=True, exist_ok=True)
        plist_path = PLIST_DIR / f"{PLIST_LABEL}.plist"

        script_path = os.path.abspath(__file__)
        log_path = str(Path.home() / "Library" / "Logs" / "qoder-ai-hot-articles.log")
Confidence
95% confidence
Finding
Creating and using a plist path under LaunchAgents is part of establishing persistence on macOS. This modifies the user's environment in a durable way beyond the core one-time report-generation purpose.

Session Persistence

Medium
Category
Rogue Agent
Content
"""安装定时任务,每天自动生成日报"""
    if sys.platform == "darwin":
        PLIST_DIR.mkdir(parents=True, exist_ok=True)
        plist_path = PLIST_DIR / f"{PLIST_LABEL}.plist"

        script_path = os.path.abspath(__file__)
        log_path = str(Path.home() / "Library" / "Logs" / "qoder-ai-hot-articles.log")
Confidence
95% confidence
Finding
Creating and using a plist path under LaunchAgents is part of establishing persistence on macOS. This modifies the user's environment in a durable way beyond the core one-time report-generation purpose.

Session Persistence

Medium
Category
Rogue Agent
Content
"""安装定时任务,每天自动生成日报"""
    if sys.platform == "darwin":
        PLIST_DIR.mkdir(parents=True, exist_ok=True)
        plist_path = PLIST_DIR / f"{PLIST_LABEL}.plist"

        script_path = os.path.abspath(__file__)
        log_path = str(Path.home() / "Library" / "Logs" / "qoder-ai-hot-articles.log")
Confidence
95% confidence
Finding
Creating and using a plist path under LaunchAgents is part of establishing persistence on macOS. This modifies the user's environment in a durable way beyond the core one-time report-generation purpose.

Session Persistence

Medium
Category
Rogue Agent
Content
<string>{api_key}</string>
        </dict>"""

        plist_content = f'''<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
Confidence
95% confidence
Finding
Constructing the plist content is a direct step in creating a persistent background task. Because the same plist can also contain the API key, the persistence mechanism meaningfully increases both execution and secret-retention risk.

Session Persistence

Medium
Category
Rogue Agent
Content
</dict>"""

        plist_content = f'''<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
Confidence
95% confidence
Finding
The plist document creation is part of the persistent execution path and is not necessary for the core reporting task. Persistent job definitions create ongoing trust and maintenance burden on the user's machine.

Session Persistence

Medium
Category
Rogue Agent
Content
</dict>"""

        plist_content = f'''<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
Confidence
95% confidence
Finding
The plist document creation is part of the persistent execution path and is not necessary for the core reporting task. Persistent job definitions create ongoing trust and maintenance burden on the user's machine.

Session Persistence

Medium
Category
Rogue Agent
Content
plist_content = f'''<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>{PLIST_LABEL}</string>
Confidence
95% confidence
Finding
Embedding the LaunchAgent label inside the plist contributes to a durable scheduled task. In this skill context, that persistence is more dangerous because it supports recurring network access and credential use.

VirusTotal

VirusTotal findings are pending for this skill version.

View on VirusTotal

Static analysis

No suspicious patterns detected.