Back to skill

Security audit

公众号订阅追踪

Security checks across malware telemetry and agentic risk

Overview

The skill largely matches its stated purpose, but its scheduled-task and API-key handling need careful review before installation.

Install only if you are comfortable giving this skill your RedFox API key, sending monitored account IDs to redfox.hk, storing subscription data under ~/.qoder, generating reports in Downloads, and optionally creating a daily scheduled job. Prefer REDFOX_API_KEY over command-line keys, avoid enabling daily push unless you need it, and review/remove any LaunchAgent or crontab entry if you stop using the skill.

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
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (17)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
script_path = os.path.abspath(__file__)
        cron_line = f"0 6 * * * /usr/bin/python3 {script_path} fetch"
        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 call builds a shell command string and executes it with shell=True to install a crontab entry. If the script path contains shell metacharacters or quotes, it can break out of the quoted context and execute unintended commands, turning a convenience feature into command injection and persistence.

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 removal path also uses shell=True with an interpolated script_path inside a grep expression. A crafted path containing quotes or shell syntax could alter the command pipeline, leading to arbitrary command execution while modifying persisted cron state.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill documentation instructs users to execute a Python script that uses environment variables, reads and writes local files, performs network access to a third-party service, and installs scheduled tasks, yet the skill declares no permissions. This creates a transparency and trust problem: users cannot accurately assess that the skill will access secrets, persist data under the home directory, contact an external API, and invoke shell-level behavior such as browser opening or cron/task installation.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The skill installs OS-level scheduled tasks via LaunchAgents and crontab, which creates persistence on the user's machine. For a content subscription utility this may be functional, but it expands the trust boundary significantly and can surprise users if not clearly consented to and removable.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The README promises a one-click scheduled task that runs daily at 06:00 and opens a browser, but it does not clearly warn that this creates a persistent system-level change. Users may unknowingly install automation that continues executing after the current session, which can surprise them, consume resources, or create a foothold for later abuse if the skill behavior changes.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The README states that the skill requires a REDFOX_API_KEY from a third-party service, but it does not clearly disclose that subscription targets, account identifiers, and article-monitoring requests will be sent to that external provider. This can mislead users about where their monitored account list and usage metadata go, creating privacy and compliance risk, especially for competitor-tracking or sensitive research workflows.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill tells users to pass the API key directly on the command line and to store it in a plaintext JSON file under ~/.qoder/apis/redfox.json, but it provides no warning that command-line arguments may be exposed via shell history or process listings and that local config files may be readable by other local users or backup/sync tools. This increases the chance of credential leakage and unauthorized use of the third-party account.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The LaunchAgent embeds the API key into the plist EnvironmentVariables section, storing a secret in a user-readable file on disk. This increases the chance of credential disclosure through local file access, backups, logs, or accidental sharing of the plist.

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
97% confidence
Finding
The command string passed to the shell includes unescaped path data, so output and command composition are not safely separated. In a hostile or unusual installation path, this can be exploited to inject additional shell commands while editing the user's crontab.

Unvalidated Output Injection

High
Category
Output Handling
Content
# 打开浏览器
            if sys.platform == "darwin":
                subprocess.run(["open", str(output_path)], check=False)
            elif sys.platform == "linux":
                subprocess.run(["xdg-open", str(output_path)], check=False)
Confidence
89% confidence
Finding
The generated HTML report includes unescaped fields from remote article data, and then the script automatically opens that file in the user's browser. An attacker controlling article title, summary, author, or URL could inject script or malicious markup into the local report, producing a stored client-side injection when viewed.

Unvalidated Output Injection

High
Category
Output Handling
Content
if sys.platform == "darwin":
                subprocess.run(["open", str(output_path)], check=False)
            elif sys.platform == "linux":
                subprocess.run(["xdg-open", str(output_path)], check=False)

        print(f"\n{GREEN}{BOLD}✓ 完成!{RESET}")
        print(f"  订阅公众号: {len(subscriptions)} 个")
Confidence
89% confidence
Finding
The Linux auto-open path triggers the same attacker-influenced HTML rendering risk as on macOS. Because remote content is written directly into HTML and then opened automatically, a malicious article record can cause script execution or browser-based phishing from a trusted local file context.

Session Persistence

Medium
Category
Rogue Agent
Content
cron_line = f"0 6 * * * /usr/bin/python3 {script_path} fetch"
        try:
            subprocess.run(
                f'(crontab -l 2>/dev/null; echo "{cron_line}") | crontab -',
                shell=True, check=True, capture_output=True
            )
            info("订阅成功! 每天 06:00 自动拉取并生成日报 (crontab)")
Confidence
96% confidence
Finding
This code installs a recurring cron job, creating persistence on the host. Persistence is sensitive because it enables repeated future execution without additional user action, and in a compromised or modified script can become a durable foothold.

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 is the entry point for installing a scheduled task, which establishes persistence on the system. In skill context, automatic persistence is more sensitive because the utility could continue running daily without ongoing user awareness.

Session Persistence

Medium
Category
Rogue Agent
Content
</dict>
</plist>'''

        plist_path.write_text(plist_content, encoding="utf-8")

        try:
            subprocess.run(["launchctl", "load", str(plist_path)], check=True, capture_output=True)
Confidence
94% confidence
Finding
Writing the plist file to LaunchAgents materializes persistent configuration on disk so it can later be loaded automatically. That makes the persistence concrete and may expose the user to unattended recurring execution and secret leakage if the file contains credentials.

Session Persistence

Medium
Category
Rogue Agent
Content
</dict>
</plist>'''

        plist_path.write_text(plist_content, encoding="utf-8")

        try:
            subprocess.run(["launchctl", "load", str(plist_path)], check=True, capture_output=True)
Confidence
94% confidence
Finding
Writing the plist file to LaunchAgents materializes persistent configuration on disk so it can later be loaded automatically. That makes the persistence concrete and may expose the user to unattended recurring execution and secret leakage if the file contains credentials.

Session Persistence

Medium
Category
Rogue Agent
Content
plist_path.write_text(plist_content, encoding="utf-8")

        try:
            subprocess.run(["launchctl", "load", str(plist_path)], check=True, capture_output=True)
            info("订阅成功! 每天 06:00 自动拉取所有订阅公众号的发文并生成日报")
            info(f"日报目录: ~/Downloads/QoderGzhReports/")
            info(f"日志: {log_path}")
Confidence
95% confidence
Finding
Loading the LaunchAgent activates daily recurring execution under the user's account. This is a persistence mechanism, which is security-sensitive because any later tampering with the script or its inputs can be repeatedly executed without additional prompting.

Tool Parameter Abuse

High
Category
Tool Misuse
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
97% confidence
Finding
The shell-based crontab removal command is vulnerable to parameter abuse because filesystem-derived data is inserted directly into a shell command. This can let a maliciously crafted script path manipulate the grep expression or shell pipeline and execute unintended commands while changing persistent scheduler state.

VirusTotal

VirusTotal findings are pending for this skill version.

View on VirusTotal

Static analysis

No suspicious patterns detected.