T01 · Skill Instruction Hijacking
- Location
SKILL.md:145- Finding
Mandatory Third-Party Attribution Tracking in Generated Recommendation Links
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This book-recommendation skill is mostly purpose-related, but it can automatically install packages, write local history/cache files, create recurring automation, and force tracked links without enough user control.
Review before installing. Use only in an isolated environment where automatic pip installs and local cache/history writes are acceptable, avoid enabling the daily automation unless you explicitly want recurring runs, and be aware that generated Qidian links include a skill attribution parameter.
SKILL.md:145Mandatory Third-Party Attribution Tracking in Generated Recommendation Links
scripts/sanjiang_picker.py:75Automatic Installation of Unpinned Packages During Normal Execution
The documentation presents a narrow book-recommendation skill, but the behavior includes environment modification (pip installs), local file import from arbitrary Excel paths, and data fetching from third-party sites rather than only the described source. This is dangerous because operators and users may approve or invoke the skill based on a much safer description than what it can actually do, enabling unexpected filesystem and execution side effects.
The documentation presents a narrow book-recommendation skill, but the behavior includes environment modification (pip installs), local file import from arbitrary Excel paths, and data fetching from third-party sites rather than only the described source. This is dangerous because operators and users may approve or invoke the skill based on a much safer description than what it can actually do, enabling unexpected filesystem and execution side effects.
The trigger phrases are extremely broad (推荐好书, 书荒, 看经典, etc.) and can overlap with ordinary conversation, causing the skill to activate in contexts the user did not intend. Because activation leads to shell/network/file activity and persistence, overbroad routing materially increases the chance of unintended external requests or local state changes.
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).
},
{
"book_id": "1047904104",
"book_name": "我的智商逐年递增",
"tier": "📈万订",
"author": "介安艺",
"category": "都市 · 都市生活",
"status": "连载总字数:78万",
"word_count": "78万",
"collect": "13万",
"recommend": "3万",
"intro": "【无系统+无女主+日常+群像+智商在线+科研+大国崛起】 陈拙重生回了婴儿时期。 但他没有系统,没有随身空间,没有叮当作响的任务提示。 他拥有的,只有一个随着年龄增长,算力不断进化的成长型大脑。 “陈拙是谁?” “他是数学界的幽灵,物理学界的暴君,科学界唯一的上帝。” 不后宫,不烂俗",
"qidian_url": "https://www.qidian.com/book/1047904104/?_trace=qidiandayrec_skill",
"has_ip": false,
"adaptations": [],
"overseas_status": "",
"overseas_highlights": [],
"overseas_forums": [],
"sbti_code": "MALO",
"
The manifest claims two modes: Sanjiang new-book picks and classic recommendations from 万订/十万均订 works with IP derivative and overseas popularity info. This script's data sources, fetching, filtering, formatting, and CLI all exclusively target the Sanjiang榜 (/bang/1/6/{date} and /info/{book_id}), and there is no code path for classic-book selection or enrichment with IP/海外信息.
The skill declares allowed-tools: with no scope while the instructions clearly require shell, network access, and persistent file reads/writes. That mismatch undermines least-privilege review and can cause the agent to execute capabilities the user did not reasonably expect, including local cache/history writes and external fetching. The risk is elevated because the skill also mentions dependency installation and file import workflows, which expand the effective attack surface beyond simple recommendation logic.
The skill description and content are entirely oriented around Chinese-language Qidian content and present the behavior as fixed, without stating that outputs are Chinese-only or giving users a language choice. Under the language/locale policy, forcing a specific language without opt-in can be a policy issue unless the locale restriction is explicitly documented and justified.
The skill encourages passing user-provided SBTI/personality text into workflows that perform external site access, but it does not warn that user input may be transmitted to third parties during recommendation operations. Even if the text is only used as a parameter internally, the surrounding design normalizes networked processing of user attributes without transparency, which is a privacy risk.
The skill writes persistent cache and recommendation history files but does not clearly warn users that their interactions may create local stored state. Undisclosed persistence is risky because it can retain behavioral preferences and recommendation history beyond the current session, exposing data to later access or misuse.
The skill instructs the agent to create an automation task for daily execution, which exceeds the core scope of a one-shot book recommendation workflow. Persistent scheduled execution can repeatedly trigger network access, filesystem writes, and unsolicited content delivery without clear per-use user consent, increasing the blast radius of any misbehavior or future compromise.
This JSON manifest-like file describes the preset library entirely in Chinese, including the user-facing description, with no indication that users can choose another language or locale. For a generally applicable preset dataset, this can violate language/locale policy by effectively forcing one language experience without documented opt-in or regional scoping.
Auto-installing Python packages exceeds the justified capability of this skill and creates unnecessary privilege and supply-chain risk. In a host agent environment, this behavior can unexpectedly modify shared runtimes, pull code from external repositories, and violate least-privilege expectations for a simple recommendation workflow.
Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.
missing = []
for import_name, pip_name in REQUIRED_PACKAGES.items():
try:
__import__(import_name)
if verbose:
print(f" ✅ {pip_name} 已安装", file=sys.stderr)
except ImportError:
Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.
missing = []
for import_name, pip_name in REQUIRED_PACKAGES.items():
try:
__import__(import_name)
if verbose:
print(f" ✅ {pip_name} 已安装", file=sys.stderr)
except ImportError:
Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.
missing = []
for import_name, pip_name in REQUIRED_PACKAGES.items():
try:
__import__(import_name)
if verbose:
print(f" ✅ {pip_name} 已安装", file=sys.stderr)
except ImportError:
The script automatically invokes pip at runtime to install packages, which introduces package-management side effects unrelated to a book recommendation skill. This can execute untrusted package installation workflows in the host environment, modify the Python environment without operator approval, and broaden the attack surface through dependency confusion, compromised mirrors, or malicious packages.
for cmd in pip_commands:
try:
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
if result.returncode == 0:
print(f"[OK] 依赖安装成功: {', '.join(pip_packages)}", file=sys.stderr)
return True
The HTTP headers hard-code Accept-Language: zh-CN,zh;q=0.9,en;q=0.8, which instructs remote services to prefer Simplified Chinese/China locale responses. This is a natural-language locale policy concern because the skill does not offer the user any language or locale choice, nor document that the tool is intentionally region-specific for compliance or operational reasons.
The optional Excel feature still introduces package-management behavior by auto-installing openpyxl, which is not necessary for safe operation of the core recommendation logic. Optional paths are still dangerous because they can be triggered in environments where outbound network access or package installation should never occur.
The Excel import path also performs automatic pip installation of openpyxl at runtime, again allowing the skill to alter the execution environment and trigger external package retrieval. Even though the command is hard-coded and not shell-injected, it is still risky because a content-recommendation skill should not self-manage packages in-process.
except ImportError:
print("[ERROR] 需要 openpyxl 库。安装: pip3 install openpyxl", file=sys.stderr)
try:
subprocess.run([sys.executable, "-m", "pip", "install", "openpyxl"],
capture_output=True, timeout=60)
import openpyxl
except Exception:
The module docstring says later requests read cache directly with '零网络请求'. However, get_latest_sanjiang_date() iterates over recent dates and performs http_get() probes whenever local cache for a checked date is missing, so routine runs can still generate network traffic even before an explicit refresh.
The code auto-installs packages by trying multiple pip commands during normal execution and startup, materially increasing risk beyond the skill's stated purpose. In an agent environment, this can mutate the host, introduce unreviewed code from external repositories, and potentially enable code execution through malicious or substituted dependencies.
The skill automatically installs Python packages at runtime by invoking pip subprocesses, which is unnecessary for a book-recommendation skill and creates a supply-chain and environment-modification risk. If package indexes, mirrors, dependency resolution, or the runtime environment are compromised, executing this skill can install and run untrusted code with the agent's privileges.
try:
if verbose:
print(f"[INFO] 尝试: {' '.join(cmd)}", file=sys.stderr)
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
if result.returncode == 0:
print(f"[OK] 依赖安装成功: {', '.join(pip_packages)}", file=sys.stderr)
installed = True
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
elif sys.platform == "win32":
print(" python -m ensurepip --upgrade", file=sys.stderr)
else:
print(" sudo apt install python3-pip # Ubuntu/Debian", file=sys.stderr)
print(" sudo yum install python3-pip # CentOS/RHEL", file=sys.stderr)
return False
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
elif sys.platform == "win32":
print(" python -m ensurepip --upgrade", file=sys.stderr)
else:
print(" sudo apt install python3-pip # Ubuntu/Debian", file=sys.stderr)
print(" sudo yum install python3-pip # CentOS/RHEL", file=sys.stderr)
return False
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
print(f"\n📌 pip 检测:", file=sys.stderr)
try:
result = subprocess.run(
[sys.executable, "-m", "pip", "--version"],
capture_output=True, text=True, timeout=10
)
No suspicious patterns detected.