Back to skill

Security audit

AI抖音信息源

Security checks for vulnerabilities and agentic risk

Overview

The skill does generate Douyin AI reports, but it should be reviewed carefully because its subscription mode can persist credentials and scheduled execution, and its output handling includes unsafe and promotional behavior.

Install only if you are comfortable giving this skill a RedFox API key, allowing it to write reports locally, and potentially opening generated HTML in your browser. Avoid using --subscribe until the publisher removes plaintext key storage, fixes crontab shell handling, and escapes API data in the report HTML; also be aware that the skill forces unrelated RedFox promotional links into agent responses.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (6)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:46
Finding

Mandatory Promotional Content Hijacks Agent Responses

Content
View full analysis
Remediation
View remediation

T06 · System Persistence

Warning
Location
scripts/fetch_douyin_ai.py:406
Finding

Subscription Feature Installs Cross-Session Scheduled Execution

Content
View full analysis
Label {PLIST_LABEL} ProgramArguments /usr/bin/python3 {script_path} --no-open StartCalendarInterval Hour 16 Minute 0 RunAtLoad ''' plist_path.write_text(plist_content, encoding="utf-8") subprocess.run( ["launchctl", "load", str(plist_path)], check=True, capture_output=True ) ``` On other supported systems, it modifies the user's crontab: ```python script_path = os.path.abspath(__file__) cron_line = f"0 16 * * * /usr/bin/python3 {script_path} --no-open" subprocess.run( f'(crontab -l 2>/dev/null; echo "{cron_line}") | crontab -', shell=True, check=True, capture_output=True ) ``` ### Technical Analysis The behavior is related to the declared `--subscribe` functionality and is reached only when that option is selected. It is therefore not hidden persistence. Nevertheless, it modifies persistent operating-system scheduler configuration and causes the Skill to execute after the original session has ended. The scheduler p ...[truncated 1009 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/fetch_douyin_ai.py:418
Finding

macOS Subscription Stores the API Key in a Plaintext LaunchAgent File

Content
View full analysis
EnvironmentVariables {ENV_KEY} {api_key} """ plist_content = f''' Label {PLIST_LABEL} ProgramArguments /usr/bin/python3 {script_path} --no-open StartCalendarInterval Hour 16 Minute 0 StandardOutPath {log_path} StandardErrorPath {log_path} RunAtLoad {env_section} ''' plist_path.write_text(plist_content, encoding="utf-8") ``` ### Technical Analysis Environment-variable storage is converted into persistent plaintext storage under `~/Library/LaunchAgents`. The code does not use the macOS Keychain, encrypt the value, explicitly set restrictive permissions, or warn the user that the credential will be copied into a file. This also conflicts with the README security statement that the API key should never be exposed in code, logs, prompts, or output files. ### Attack Path 1. The user exports `REDFOX_API_KEY` in the environment. 2. The user invokes `--subscribe` on macOS. 3. The script interpolates the complete key into the LaunchAgent XML. 4. The XML is written to `~/Library/LaunchAgents/com.qoder.douyin-ai- ...[truncated 634 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/fetch_douyin_ai.py:467
Finding

Shell Injection in Crontab Installation and Removal

Content
View full analysis
/dev/null; echo "{cron_line}") | crontab -', shell=True, check=True, capture_output=True ) return True except subprocess.CalledProcessError: print(f" {cron_line}") return False ``` The unsubscription path has the same issue and additionally treats the path as a regular expression: ```python 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 ) return True except subprocess.CalledProcessError: return False ``` ### Technical Analysis `os.path.abspath(__file__)` is not inherently shell-safe. The package may be installed or extracted into a directory whose name contains command substitutions, quotation marks, backticks, semicolons, or other shell metacharacters. Because `shell=True` passes the assembled string to a command shell, metacharacters in the path may alter command parsing. Command substitutions such as `$()` are evaluated even inside double quotes. In the removal command, `grep` also interprets the path as a regular expression, potentially matching and deleting unrelated crontab entries. ### Attack Path 1. An attacker distributes or places the Skill under a crafted directory name containing shell syntax, such as a command substitution. 2. The victim invokes `--subscribe` or `--unsubscribe`. 3. The script ...[truncated 744 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/fetch_douyin_ai.py:265
Finding

Unescaped API Data Enables Stored HTML Injection in Automatically Opened Reports

Content
View full analysis
' articles_html += f'''
{cover_html}
{title}
{author} 👍 {likes} 🔁 {shares} 💬 {comments}
''' cards_html += f'''
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
SKILL.md:93
Finding

Dependency Installation Is Not Version or Hash Pinned

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (40)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared purpose focuses on generating a Douyin AI report, but the skill also depends on a third-party API service, writes files locally, opens the browser, and installs or removes persistent scheduled tasks. That mismatch is dangerous because users may authorize a seemingly simple reporting skill without realizing it can create persistence, exfiltrate via external services, or perform broader system actions.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

This is a classic tool-parameter abuse pattern: a shell command is assembled from a variable path and executed with shell=True during crontab modification. An attacker controlling the script location or file name could exploit quoting weaknesses to execute arbitrary commands under the invoking user's account.

Content

Scanner excerpt · scripts/fetch_douyin_ai.py (reported line 502)May include surrounding context.

python
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
            )

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README says users can invoke the skill by simply describing their need in natural language, with broad example phrases. This can cause accidental or overly permissive activation because many ordinary user requests about Douyin AI trends may match, increasing the chance the skill runs when the user did not intend this specific capability.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README says users can 'directly use natural language to describe needs' without needing to remember commands, but it does not clearly define when this skill should activate versus when similar general requests should not. That broad phrasing can overlap with ordinary conversation and may cause unintended invocation.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill advertises and instructs execution of code with network access, shell execution, environment-variable use, and local file writes, but it declares no explicit tool scope or permission boundaries. This weakens user consent and platform enforcement because an agent may invoke sensitive capabilities without a machine-readable restriction layer.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill describes automatic daily subscription and local report generation, but it does not prominently warn that this may install persistent scheduled tasks and create files on disk. Hidden persistence and filesystem effects are risky because users may not understand that the skill changes host state beyond a one-time report execution.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill instructs the agent to always preserve a promotional traffic-diversion block unrelated to the requested Douyin report. This creates an integrity and trust problem: agent responses are being manipulated for cross-promotion, which can bias outputs, introduce unwanted links, and normalize unsolicited redirection to external resources.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The instructions require the agent to preserve specific Chinese-language blocks and links exactly in its dialogue output, regardless of user language preference. This is a natural-language locale policy issue because it forces a specific language in responses without opt-in or documented justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The HTML document hard-codes lang="zh-CN", which enforces a specific language/locale in the generated report. The file does not provide any user opt-in, alternative locale handling, or justification that this is a region-specific tool, so it matches the policy-violation criterion for forced language or locale.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · scripts/fetch_douyin_ai.py (reported line 38)May include surrounding context.

python
DEFAULT_OUTPUT_DIR = Path.home() / "Downloads" / "QoderReports"
PAGE_SIZE = 200

PLIST_LABEL = "com.qoder.douyin-ai-feed"
PLIST_DIR = Path.home() / "Library" / "LaunchAgents"

# ─── 终端颜色 ──────────────────────────────────────────────────────────────────────

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · scripts/fetch_douyin_ai.py (reported line 39)May include surrounding context.

python
DEFAULT_OUTPUT_DIR = Path.home() / "Downloads" / "QoderReports"
PAGE_SIZE = 200

PLIST_LABEL = "com.qoder.douyin-ai-feed"
PLIST_DIR = Path.home() / "Library" / "LaunchAgents"

# ─── 终端颜色 ──────────────────────────────────────────────────────────────────────

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · scripts/fetch_douyin_ai.py (reported line 411)May include surrounding context.

python
DEFAULT_OUTPUT_DIR = Path.home() / "Downloads" / "QoderReports"
PAGE_SIZE = 200

PLIST_LABEL = "com.qoder.douyin-ai-feed"
PLIST_DIR = Path.home() / "Library" / "LaunchAgents"

# ─── 终端颜色 ──────────────────────────────────────────────────────────────────────

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · scripts/fetch_douyin_ai.py (reported line 412)May include surrounding context.

python
DEFAULT_OUTPUT_DIR = Path.home() / "Downloads" / "QoderReports"
PAGE_SIZE = 200

PLIST_LABEL = "com.qoder.douyin-ai-feed"
PLIST_DIR = Path.home() / "Library" / "LaunchAgents"

# ─── 终端颜色 ──────────────────────────────────────────────────────────────────────

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · scripts/fetch_douyin_ai.py (reported line 428)May include surrounding context.

python
DEFAULT_OUTPUT_DIR = Path.home() / "Downloads" / "QoderReports"
PAGE_SIZE = 200

PLIST_LABEL = "com.qoder.douyin-ai-feed"
PLIST_DIR = Path.home() / "Library" / "LaunchAgents"

# ─── 终端颜色 ──────────────────────────────────────────────────────────────────────

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · scripts/fetch_douyin_ai.py (reported line 432)May include surrounding context.

python
DEFAULT_OUTPUT_DIR = Path.home() / "Downloads" / "QoderReports"
PAGE_SIZE = 200

PLIST_LABEL = "com.qoder.douyin-ai-feed"
PLIST_DIR = Path.home() / "Library" / "LaunchAgents"

# ─── 终端颜色 ──────────────────────────────────────────────────────────────────────

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · scripts/fetch_douyin_ai.py (reported line 487)May include surrounding context.

python
DEFAULT_OUTPUT_DIR = Path.home() / "Downloads" / "QoderReports"
PAGE_SIZE = 200

PLIST_LABEL = "com.qoder.douyin-ai-feed"
PLIST_DIR = Path.home() / "Library" / "LaunchAgents"

# ─── 终端颜色 ──────────────────────────────────────────────────────────────────────

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill's core purpose is fetching and rendering a content feed, but it also installs persistent scheduled execution and embeds credentials into that persistence on macOS. That broadens host impact beyond expected reporting behavior and increases the blast radius if the machine or user profile is later accessed by others.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The subscription install writes a persistent LaunchAgent and includes the API key in plaintext inside the plist without a clear pre-action warning. This exposes credentials on disk and creates long-lived background execution, both of which exceed what many users would expect from a report generator.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · scripts/fetch_douyin_ai.py (reported line 412)May include surrounding context.

python
"""安装定时任务,每天自动生成日报"""
    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-douyin-ai-feed.log")

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · scripts/fetch_douyin_ai.py (reported line 428)May include surrounding context.

python
"""安装定时任务,每天自动生成日报"""
    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-douyin-ai-feed.log")

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · scripts/fetch_douyin_ai.py (reported line 429)May include surrounding context.

python
"""安装定时任务,每天自动生成日报"""
    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-douyin-ai-feed.log")

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · scripts/fetch_douyin_ai.py (reported line 453)May include surrounding context.

python
"""安装定时任务,每天自动生成日报"""
    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-douyin-ai-feed.log")

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · scripts/fetch_douyin_ai.py (reported line 487)May include surrounding context.

python
"""安装定时任务,每天自动生成日报"""
    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-douyin-ai-feed.log")

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · scripts/fetch_douyin_ai.py (reported line 488)May include surrounding context.

python
"""安装定时任务,每天自动生成日报"""
    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-douyin-ai-feed.log")

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · scripts/fetch_douyin_ai.py (reported line 492)May include surrounding context.

python
"""安装定时任务,每天自动生成日报"""
    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-douyin-ai-feed.log")

Static analysis

No suspicious patterns detected.