T01 · Skill Instruction Hijacking
- Location
SKILL.md:46- Finding
Mandatory Promotional Content Hijacks Agent Responses
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
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.
SKILL.md:46Mandatory Promotional Content Hijacks Agent Responses
scripts/fetch_douyin_ai.py:406Subscription Feature Installs Cross-Session Scheduled Execution
scripts/fetch_douyin_ai.py:418macOS Subscription Stores the API Key in a Plaintext LaunchAgent File
scripts/fetch_douyin_ai.py:467Shell Injection in Crontab Installation and Removal
scripts/fetch_douyin_ai.py:265Unescaped API Data Enables Stored HTML Injection in Automatically Opened Reports
SKILL.md:93Dependency Installation Is Not Version or Hash Pinned
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.
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.
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
)
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.
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.
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.
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.
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.
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.
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.
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.
DEFAULT_OUTPUT_DIR = Path.home() / "Downloads" / "QoderReports"
PAGE_SIZE = 200
PLIST_LABEL = "com.qoder.douyin-ai-feed"
PLIST_DIR = Path.home() / "Library" / "LaunchAgents"
# ─── 终端颜色 ──────────────────────────────────────────────────────────────────────
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.
DEFAULT_OUTPUT_DIR = Path.home() / "Downloads" / "QoderReports"
PAGE_SIZE = 200
PLIST_LABEL = "com.qoder.douyin-ai-feed"
PLIST_DIR = Path.home() / "Library" / "LaunchAgents"
# ─── 终端颜色 ──────────────────────────────────────────────────────────────────────
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.
DEFAULT_OUTPUT_DIR = Path.home() / "Downloads" / "QoderReports"
PAGE_SIZE = 200
PLIST_LABEL = "com.qoder.douyin-ai-feed"
PLIST_DIR = Path.home() / "Library" / "LaunchAgents"
# ─── 终端颜色 ──────────────────────────────────────────────────────────────────────
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.
DEFAULT_OUTPUT_DIR = Path.home() / "Downloads" / "QoderReports"
PAGE_SIZE = 200
PLIST_LABEL = "com.qoder.douyin-ai-feed"
PLIST_DIR = Path.home() / "Library" / "LaunchAgents"
# ─── 终端颜色 ──────────────────────────────────────────────────────────────────────
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.
DEFAULT_OUTPUT_DIR = Path.home() / "Downloads" / "QoderReports"
PAGE_SIZE = 200
PLIST_LABEL = "com.qoder.douyin-ai-feed"
PLIST_DIR = Path.home() / "Library" / "LaunchAgents"
# ─── 终端颜色 ──────────────────────────────────────────────────────────────────────
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.
DEFAULT_OUTPUT_DIR = Path.home() / "Downloads" / "QoderReports"
PAGE_SIZE = 200
PLIST_LABEL = "com.qoder.douyin-ai-feed"
PLIST_DIR = Path.home() / "Library" / "LaunchAgents"
# ─── 终端颜色 ──────────────────────────────────────────────────────────────────────
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.
DEFAULT_OUTPUT_DIR = Path.home() / "Downloads" / "QoderReports"
PAGE_SIZE = 200
PLIST_LABEL = "com.qoder.douyin-ai-feed"
PLIST_DIR = Path.home() / "Library" / "LaunchAgents"
# ─── 终端颜色 ──────────────────────────────────────────────────────────────────────
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.
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.
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.
"""安装定时任务,每天自动生成日报"""
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")
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.
"""安装定时任务,每天自动生成日报"""
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")
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.
"""安装定时任务,每天自动生成日报"""
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")
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.
"""安装定时任务,每天自动生成日报"""
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")
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.
"""安装定时任务,每天自动生成日报"""
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")
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.
"""安装定时任务,每天自动生成日报"""
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")
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.
"""安装定时任务,每天自动生成日报"""
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")
No suspicious patterns detected.