Back to skill

Security audit

PubMed Search

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its PubMed search purpose, but its recommended install path runs mutable remote code and the runtime can print PubMed API credentials into logs.

Review before installing. Prefer the documented pip/venv path over curl|sh or unpinned npx, pin or verify dependencies where possible, and avoid setting a PubMed API key unless needed. If you do use a key, treat console output and agent transcripts as potentially sensitive because the tool may print URLs containing the key and email.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (3)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:42
Finding

Unverified Remote Installer Is Piped Directly into a Shell

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
pubmed_search.py:47
Finding

PubMed API Key Is Disclosed Through Search URL Logging

Content
View full analysis
dict: """获取 API 请求参数""" params = { 'tool': self.tool, 'retmode': 'xml' } if self.api_key: params['api_key'] = self.api_key if self.email: params['email'] = self.email if extra_params: params.update(extra_params) return params ``` Construction of a credential-bearing URL: ```python params = self.config.get_params({ "db": "pubmed", "term": query, "retmax": str(num_results) }) return f"{base_url}?{'&'.join([f'{k}={v}' for k, v in params.items()])}" ``` Logging by the keyword and advanced search paths: ```python search_url = self.generate_search_url(term=keywords, num_results=num_results) print(f"搜索 URL: {search_url}") ``` ```python search_url = self.generate_search_url( term=term, title=title, author=author, journal=journal, start_date=start_date, end_date=end_date, num_results=num_results ) print(f"搜索 URL: {search_url}") ``` ### Technical Analysis When `PUBMED_API_KEY` is configured, `Config.get_params()` inserts it into the parameter dictionary. `generate_search_url()` serializes that dictionary into the query string, after which both search methods print the complete URL. As a result, the API key can be exposed in terminal capture, CI logs, redirected output, application logs, AI Agent transcripts, or other monitoring systems. The configured email address is also included in the same URL and output. Sending the API key and email over HTTPS to the documented NCBI API is consistent with the Skill's declared functionality and is not evidence of covert exfiltration. The vulnerability i ...[truncated 1027 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:4
Finding

Mutable and Unpinned Dependencies Create Supply-Chain Exposure

Content
View full analysis
=2.31.0 # 环境变量管理 (可选) python-dotenv>=1.0.0 ``` `README.md:24-27`: ```bash npx skills add https://github.com/JackKuo666/pubmed-search-skill.git ``` Representative dependency installation commands include: ```bash uv pip install -r requirements.txt ``` ```bash pip install -r requirements.txt ``` ### Technical Analysis The Python dependencies use lower-bound-only constraints. A future installation can therefore resolve to versions that did not exist when this Skill was audited. No lock file or package hashes are supplied to establish artifact integrity. The recommended `npx skills` installation command also does not pin the invoked npm package version, while the GitHub repository URL is not fixed to an immutable commit. This allows the installed Skill or installer behavior to change independently of the reviewed artifact. There is no evidence in the audited files that `requests`, `python-dotenv`, or the referenced repository are currently malicious. The confirmed issue is that the installation process does not provide reproducible or cryptographically verified dependency resolution. ### Attack Path 1. A user follows the documented `npx`, `pip`, or `uv pip` installation path. 2. The package manager resolves the latest package versions satisfying the broad constraints, or retrieves the current state of a mutable repository. 3. A future compromised, malicious, or incompatible release is selected instead of the version originally reviewed. 4. Package installation hooks or subsequently imported dependency code execute in the Skill's Python environment. 5. The altered component inherits the permissions and data access of the user running the Skill. ## ...[truncated 379 chars]
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (23)

Chaining Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

The curl ... | sh pattern is especially dangerous because it combines retrieval and execution into a single opaque step, preventing meaningful inspection before code runs. In a skill README, this increases the chance that users will blindly execute remote shell commands with their local user privileges, enabling full compromise of the workstation if the upstream content is malicious or tampered with.

Content

Scanner excerpt · README.md (reported line 59)May include surrounding context.

bash
# Install uv (if not already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Create virtual environment and install dependencies
cd ~/.claude/skills/pubmed-search-skill

Chaining Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

Piping curl output directly into sh creates an immediate command-execution chain with no opportunity for review or integrity checks. In a skill file, this is especially risky because users may copy-paste the command verbatim, turning documentation into a code-execution vector.

Content

Scanner excerpt · SKILL.md (reported line 44)May include surrounding context.

Method 1: Using uv (Recommended - Fastest)

bash
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# Create virtual environment and install dependencies
cd /path/to/pubmed-search-skill

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 71)May include surrounding context.

md
print("安装命令: pip install requests")
    sys.exit(1)

# 加载 .env 文件
try:
    from dotenv import load_dotenv
    load_dotenv()

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 73)May include surrounding context.

md
print("安装命令: pip install requests")
    sys.exit(1)

# 加载 .env 文件
try:
    from dotenv import load_dotenv
    load_dotenv()

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · pubmed_search.py (reported line 23)May include surrounding context.

python
print("安装命令: pip install requests")
    sys.exit(1)

# 加载 .env 文件
try:
    from dotenv import load_dotenv
    load_dotenv()

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

The tool embeds untrusted remote content such as article titles and abstracts directly into a generated analysis prompt without delimiting or sanitizing it. If that prompt is later passed to another LLM, malicious or adversarial text in the paper metadata could perform prompt injection, influencing downstream model behavior, causing instruction override, or inducing leakage of surrounding context and tool outputs.

Content

Scanner excerpt · pubmed_search.py (reported line 415)May include surrounding context.

python
请基于论文信息进行全面、客观的分析。如果摘要中缺少某些信息,请指出这一点,并根据专业知识提供可能的推断或建议。
"""
        return prompt


# ============================================

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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 · README.md (reported line 61)May include surrounding context.

md
# Install uv (if not already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Create virtual environment and install dependencies
cd ~/.claude/skills/pubmed-search-skill
uv venv
source .venv/bin/activate  # Linux/macOS

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill declares no explicit tool scope even though its content clearly implies network access, file writes, and environment-variable usage. Without a permissions or allowed-tools boundary, an agent may over-grant capabilities or invoke the skill in contexts broader than intended, increasing the chance of unintended data access or side effects.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Natural-language strings throughout the file, including the module description and CLI help, are presented exclusively in Chinese with no option to select another language. This can violate language/locale policy when the skill does not offer user choice or document a justified locale restriction.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest description limits the skill to searching and analyzing biomedical literature. The code adds a separate content-acquisition and local file write capability by fetching PMC PDF files and persisting them under a user-specified directory, which goes beyond search/analysis behavior.

Content

No source excerpt is available for this finding.

External Script Fetching

Low
Category
Supply Chain
Confidence
92% confidence
Finding

The README instructs users to fetch and execute a remote installer script directly from the network. If the remote host, transport path, or published script is compromised, users may execute attacker-controlled code on their machine during installation.

Content

Scanner excerpt · README.md (reported line 59)May include surrounding context.

bash
# Install uv (if not already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Create virtual environment and install dependencies
cd ~/.claude/skills/pubmed-search-skill

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The console and Markdown output examples show user-facing labels in Chinese (for example, 作者, 期刊, 摘要, 搜索结果) even though the rest of the README is in English. This suggests the skill may force a specific output language or locale without user opt-in, which is a natural-language policy concern under the language/locale rule.

Content

No source excerpt is available for this finding.

External Script Fetching

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The installation instructions fetch and execute a remote script via curl from the network. This is dangerous because compromise of the remote host, DNS, TLS trust chain, or the script itself could lead to arbitrary code execution on the user's machine during setup.

Content

Scanner excerpt · SKILL.md (reported line 44)May include surrounding context.

Method 1: Using uv (Recommended - Fastest)

bash
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# Create virtual environment and install dependencies
cd /path/to/pubmed-search-skill

Vague Triggers

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The activation guidance is broad: it suggests using the skill whenever users request literature search or analysis, without clear boundaries for when network access, downloads, or local file output should occur. In agent environments, vague triggers can cause the skill to run too eagerly and perform unnecessary external requests or file operations.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The skill loads a local .env file and reads environment variables for API configuration and identity data. While this may support API usage, local configuration file access is not part of the stated search/analysis purpose and is an additional capability not described in the manifest.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

This code creates the output directory and writes a PDF file to disk, which is a safety-relevant file write operation. Although the function reports progress and the CLI exposes an output directory argument, there is no explicit warning or confirmation about creating files locally or potentially overwriting existing content.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The manifest says the tool is for searching and analyzing PubMed literature, which implies the code performs analysis. In practice, generate_analysis only formats metadata and abstract into a prompt template for a downstream analyst, so the implemented behavior is weaker than the stated capability.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The file’s natural-language comments are written only in Chinese, which imposes a specific language/locale choice without offering an alternative or opt-in. Under the policy, language-only instructions or documentation can be a locale-policy issue when no choice is provided.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
91% confidence
Finding

The dependency specification uses a lower-bound constraint (requests>=2.31.0) instead of pinning to a known-good version, which makes builds non-reproducible and can silently pull in vulnerable or breaking releases. In a security-sensitive tool that performs HTTP requests, this increases supply-chain risk and makes it hard to verify whether deployed environments are protected from known requests advisories.

Content

Scanner excerpt · requirements.txt (reported line 4)May include surrounding context.

text
# PubMed-Search 依赖列表

# HTTP 请求
requests>=2.31.0

# 环境变量管理 (可选)
python-dotenv>=1.0.0

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
84% confidence
Finding

The manifest references requests without pinning, and the package has multiple known advisories across versions. Because the exact installed version is unknowable from this file, the project may resolve to an affected release, which is especially relevant for a PubMed-search skill that relies on outbound HTTP and could handle credentials, redirects, or session state.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
88% confidence
Finding

The dependency specification uses python-dotenv>=1.0.0 without an exact pin, so installations may resolve to different versions over time. This weakens reproducibility and can expose the project to supply-chain or known-vulnerability risk if a later resolved version is unsafe.

Content

Scanner excerpt · requirements.txt (reported line 7)May include surrounding context.

text
requests>=2.31.0

# 环境变量管理 (可选)
python-dotenv>=1.0.0

Unverifiable Dependency: python-dotenv has 2 known advisory(ies) (CVE-2026-28684 (python-dotenv: Symlink following in set_key allows arbitrary file overwrite via ); CVE-2026-28684 (python-dotenv reads key-value pairs from a .env file and can set them as environ)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
78% confidence
Finding

The manifest references python-dotenv without pinning, while advisories exist for some versions. If this optional package is installed in an affected version, environment file handling could introduce local file or configuration risks depending on how the application uses it.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.