T09 · Insecure Skill Coding Practices
- Location
scripts/ai_summarize.py:150- Finding
Shell Command Injection Through PDF-Controlled Notification Content
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This PDF paper-management skill is mostly purpose-aligned, but it includes an unsafe notification command path and under-disclosed automatic file deletion/renaming behavior that users should review before installing.
Review this skill before installing. Use it only on directories you intentionally dedicate to paper management, avoid enabling cron until you understand the move/rename/delete behavior, and leave notifications disabled unless the shell command execution path is fixed or tightly controlled. Do not assume the advertised AI summarization sends data to OpenAI in this version; the inspected code appears to summarize locally despite OpenAI-related configuration and dependencies.
scripts/ai_summarize.py:150Shell Command Injection Through PDF-Controlled Notification Content
scripts/auto_index.sh:43Undocumented Permanent Deletion of Duplicate Downloads
requirements.txt:4Unbounded and Unhashed Third-Party Dependencies
The README says AI summarization can be enabled but does not warn that full PDF text may be transmitted to an external API provider. Because research papers may contain unpublished, licensed, or sensitive content, failing to disclose external data transfer creates a meaningful confidentiality and compliance risk.
The skill includes a configurable external notification command that can execute arbitrary programs and exfiltrate paper summaries outside the application boundary. In a literature-management context, this greatly expands attack surface beyond the stated purpose and creates both command-execution and unintended data-disclosure risk, especially since summaries may contain proprietary or sensitive research text.
This is a classic tool-parameter abuse issue: a shell-enabled subprocess is fed a constructed command string derived from configurable parameters and content. Because the feature executes in the host environment, successful abuse can lead to arbitrary command execution, lateral movement, or persistence, making the skill context significantly more dangerous than a simple local notifier.
# 执行外部通知命令
try:
cmd = f'{notify_cmd} "{title}" "{message[:1500]}"'
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30)
if result.returncode == 0:
print(f"✓ 通知已发送")
return True
The user-facing documentation is entirely in Chinese, including commands and descriptions, with no indication that other languages are supported or that the language choice is intentional and limited to a specific audience. Under the stated policy, forcing a specific language without opt-in or justification can be a natural-language policy violation.
The README describes an automated workflow that moves files from downloads/ into papers/ and renames them, but it does not clearly warn users that their original filenames and directory placement will be changed automatically. In a file-management skill, undocumented destructive or state-changing behavior can cause confusion, broken references, accidental data loss, or processing of the wrong files, especially when run unattended via cron.
The skill advertises operational behavior that clearly implies shell execution, file reads/writes, and environment variable access, but it does not declare any explicit tool scope or permission boundaries. This creates an overbroad-trust condition where an agent may invoke powerful capabilities without transparent user review or least-privilege constraints, increasing the risk of unintended file modification, data exposure, or command execution.
The manifest description and primary content are written in Chinese, and the file does not indicate that the skill supports other languages or that Chinese is a required locale. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation.
The module docstring describes an 'AI智能文献提炼模块' with configuration for AI providers and models such as OpenAI/Anthropic. However, the implementation generates summaries entirely through local section extraction and string truncation in generate_summary, and never invokes any AI provider or model. This is a clear mismatch between the advertised behavior and the actual code behavior.
The save_summary docstring states it saves 'AI提炼结果', and the module-level comments repeatedly describe the feature as AI-based summarization. In reality, the code never calls an AI system; it extracts sections with regex and concatenates them into a formatted summary. This is an active contradiction in the code documentation, not merely an omitted detail.
The function transmits generated summary content to an external command without an explicit user-facing warning, confirmation, or data-classification check. Even if the command is intended for local notification, the design permits silent disclosure of research content to arbitrary handlers, which is risky in environments managing unpublished or licensed documents.
The code builds a shell command string from configurable input (notify_cmd) plus dynamic content (title and message) and executes it with shell=True. This creates a command-injection surface and allows arbitrary OS command execution if the configuration or any interpolated argument contains shell metacharacters or crafted quoting, which is especially dangerous because the feature is unrelated to core summarization behavior.
# 执行外部通知命令
try:
cmd = f'{notify_cmd} "{title}" "{message[:1500]}"'
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30)
if result.returncode == 0:
print(f"✓ 通知已发送")
return True
The script unconditionally deletes files from the downloads directory with rm -f when their hash already exists in the database. Although the action is logged, there is no prior user disclosure or confirmation in the script comments indicating that duplicate downloaded PDFs will be removed automatically.
This code file contains natural-language text in Chinese in the module docstring, and later emits Chinese-only status and error messages. The policy forbids forcing a specific language or locale unless the skill offers user choice or clearly documents a justified locale restriction, which is not present here.
The function returns and prints Chinese-only messages such as extraction errors, progress, and completion notices. Because the file provides no language selection, fallback, or justification for a Chinese-only interface, this appears to violate the language/locale policy.
The script performs on-disk file renaming, which is a destructive side effect not clearly reflected in the higher-level skill description that focuses on indexing, search, and metadata extraction. In an agent setting, this mismatch can cause unintended modification of a user's document library if the rename command is invoked without the user understanding that files will be moved/renamed.
The code calls os.rename on user PDF files without any confirmation, approval gate, or rollback support. If metadata extraction is inaccurate or filenames collide unexpectedly, the user's files can be renamed in confusing ways, disrupting downstream workflows, citations, sync tools, or external references.
The activation description is broad and trigger-based, covering general tasks like managing PDFs, indexing, searching, and metadata extraction without clear scoping or invocation boundaries. In an agent environment, this can cause over-activation on loosely related user requests, leading the skill to access local files or process documents when the user did not explicitly intend to invoke it.
The manifest description is entirely in Chinese and presents the skill as operating in that language, but it does not state that the skill is China-specific or offer any language choice. This can violate language/locale policy when users have not opted into Chinese output or a Chinese-only experience.
The config includes a natural-language trigger/value of "科研通" under download keywords, which implies behavior tailored to a specific language/locale. There is no accompanying indication in this file that users can choose locale-specific keywords or that the restriction is documented and justified.
PyMuPDF is specified with a lower-bound only constraint, which permits installation of any newer release, including potentially breaking or vulnerable versions. In a document-processing skill that handles PDFs, dependency drift increases supply-chain risk and makes builds non-reproducible, especially because PDF parsers are historically security-sensitive.
# Paper Management System Dependencies
# PDF processing
PyMuPDF>=1.23.0
# AI summarization (optional)
openai>=1.0.0
PyMuPDF has known advisories, and because the manifest does not pin a version, it is impossible to determine whether deployments will pull an affected release. This is more dangerous in this skill because it explicitly processes PDFs, making a vulnerable parser or related utility more likely to be reachable.
The openai package is not pinned to an exact version, so future installs may resolve to materially different code than was tested. This creates supply-chain and stability risk, though the direct security impact in this manifest alone is limited because no exploit path is shown here.
PyMuPDF>=1.23.0
# AI summarization (optional)
openai>=1.0.0
anthropic>=0.20.0
# Configuration
The anthropic dependency is unpinned, allowing uncontrolled upgrades to versions that may introduce vulnerabilities or unsafe behavior changes. Because this package may interact with local files or tool ecosystems in agent contexts, lack of version control is more concerning than for a purely isolated library.
# AI summarization (optional)
openai>=1.0.0
anthropic>=0.20.0
# Configuration
pyyaml>=6.0
The anthropic SDK has listed advisories, and without version pinning the deployed package may silently fall into an affected range. In an agent-oriented environment, SDK flaws involving filesystem permissions or path validation can have outsized impact if local tool or file access is enabled.
PyYAML has a history of unsafe deserialization issues, and specifying only a minimum version means installations may vary in ways that are hard to audit. In a system that may load configuration from YAML, dependency ambiguity increases the chance of deploying an affected or behaviorally unsafe release.
anthropic>=0.20.0
# Configuration
pyyaml>=6.0
# Development
pytest>=7.0.0
No suspicious patterns detected.