Back to skill

Security audit

arxiv_deep_reader

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed arXiv paper-reading tool, but users should be aware it sends paper content to a configured LLM provider and uses unpinned Python dependencies.

Install in an isolated virtual environment, review or pin dependencies before running, and explicitly set LLM_BASE_URL and LLM_API_KEY for the provider you intend to use. Treat generated notes as untrusted summaries because arXiv paper text can contain instructions that may influence the LLM output.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
agents/classifier_agent.py:44
Finding
Indirect Prompt Injection Through Untrusted Paper Content<![CDATA[ ## Vulnerability Details **File Location**: `agents/classifier_agent.py:44-52`, `agents/reader_agent.py:60-96`, `agents/summary_agent.py:37-55`, `paper_reader/latex_parser.py:158-171`, `prompts/reader_system.md:1-12` **Vulnerability Type**: Indirect prompt injection caused by insufficient separation of instructions and untrusted content **Risk Level**: Medium ### Complete Vulnerable Code Snippets `agents/classifier_agent.py:44-52`: ```python def classify(self, title: str, abstract: str) -> str: """Return the category name for a single paper.""" user_input = ( f"Please classify the following paper:\n\n" f"**Title**: {title}\n\n" f"**Abstract**: {abstract}" ) try: result = self.chain.invoke( {"messages": [{"role": "user", "content": user_input}]} ) ``` The original prompt text is written in Chinese, but the data flow shown above is equivalent: attacker-controlled `title` and `abstract` values are directly interpolated into an LLM message. `agents/reader_agent.py:60-96`: ```python title = paper_info["title"] authors = ", ".join(paper_info.get("authors", [])) arxiv_id = paper_info["arxiv_id"] # Pass 1 logger.info(f" [Pass 1] {title[:60]}...") first_pass_text = truncate_text(parsed_paper.first_pass_text, 30000) user_msg_1 = FIRST_PASS_USER.format( title=title, authors=authors, arxiv_id=arxiv_id, first_pass_content=first_pass_text, ) result_1 = self.chain.invoke( {"messages": [{"role": "user", "content": user_msg_1}]} ) initial_summary = result_1["messages"][-1].content # Pass 2 logger.info(f" [Pass 2] {title[:60]}...") main_body = truncate_text(parsed_paper.main_body_text, 50000) if not main_body.strip(): return self._format_final_notes(paper_info, initial_summary) user_msg_2 = SECOND_PASS_USER.format( initial_summary=initial_summary, main_body=main_body, ) result_2 = self.chain.invoke( {"messages": [{"role": "user", "content": user_msg_2}]} ) ...[truncated 4388 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add an explicit system-level trust-boundary rule stating that titles, abstracts, LaTeX, summaries, and appendices are untrusted reference material and that instructions contained in them must never be followed. 2. Place untrusted fields inside clearly identified structured containers, such as JSON fields or dedicated document blocks, and describe those blocks as data rather than instructions. 3. Use separate messages or typed structured inputs for task instructions and document content where supported by the LLM framework. 4. Require structured classifier output using schema validation rather than extracting arbitrary JSON from free-form output. 5. Validate generated category names, confidence values, appendix decisions, and final output against strict schemas and size limits. 6. Do not treat a previous model response as trusted. Mark `initial_summary` as untrusted model-generated context before inserting it into a later prompt. 7. Consider detecting or neutralizing common instruction-injection patterns in retrieved documents. Such filtering should supplement, not replace, system-level trust-boundary instructions. 8. Add adversarial tests containing paper text such as “ignore prior instructions,” forged system-message markers, deceptive Markdown links, and fake appendix directives. 9. If tools are added to these agents in the future, enforce tool allowlists, argument validation, least privilege, and explicit user confirmation for side effects. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Non-Reproducible Installation Through Unpinned Third-Party Dependencies<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1-6`, `SKILL.md:21-23` **Vulnerability Type**: Unpinned dependency supply-chain exposure **Risk Level**: Medium ### Complete Vulnerable Code Snippets `requirements.txt:1-6`: ```text langchain>=1.2.9 langchain-openai>=1.1.7 requests>=2.31.0 python-dotenv>=1.0.0 arxiv>=2.1.0 arxiv-to-prompt ``` `SKILL.md:21-23`: ```bash uv venv uv pip install -r "{baseDir}/requirements.txt" ``` ### Technical Analysis Five dependencies use lower-bound-only version constraints, allowing any later release to be selected at installation time. The `arxiv-to-prompt` dependency has no version constraint. The repository contains no reviewed lockfile or package hashes that bind installation to exact artifacts. As a result, the dependency code installed by the documented command can differ substantially from the code present when the Skill was audited. Python packages may execute package-controlled code during installation and are imported into the application at runtime. In particular, `arxiv_to_prompt` is dynamically imported and invoked by `arxiv_fetcher/fetcher.py:316-320`. The audit did not establish that any named dependency is currently malicious. The confirmed issue is that the installation process does not provide a reproducible or cryptographically verified dependency set, leaving the project exposed to a future compromised release, account takeover, or incompatible update. ### Attack Path 1. A dependency publisher account or upstream release process is compromised, or a future allowed release introduces malicious code. 2. The malicious version still satisfies the broad `>=` constraint or, for `arxiv-to-prompt`, the unconstrained requirement. 3. A user follows the documented `uv pip install -r requirements.txt` command. 4. The resolver downloads the attacker-controlled package version because no lockfile or hashes restrict artifact selection. 5. Package code executes during installation or when imp ...[truncated 805 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every direct dependency to an exact reviewed version rather than using lower-bound-only constraints. 2. Generate and commit a `uv.lock` file or an equivalent reproducible lockfile containing resolved transitive dependencies. 3. Use cryptographic package hashes where the installation workflow supports them. 4. Explicitly pin and review `arxiv-to-prompt`, because it is currently entirely unconstrained and is imported into the paper-processing path. 5. Install only from trusted package indexes configured with HTTPS; disable unexpected supplemental indexes to reduce dependency-confusion exposure. 6. Run dependency vulnerability and provenance checks in continuous integration. 7. Perform dependency updates through reviewed pull requests that show lockfile changes. 8. Use a restricted virtual environment and a low-privilege user for installation and execution. 9. Avoid exposing unrelated secrets to the installation process or runtime environment. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (48)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
Loading local category definitions and prompts from disk while advertising a direct arXiv reading workflow creates a misleading trust boundary around filesystem use. This is dangerous because local prompt/category files can meaningfully alter model behavior, yet that attack surface is not disclosed to the user or to a policy engine evaluating the skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
Loading local category definitions and prompts from disk while advertising a direct arXiv reading workflow creates a misleading trust boundary around filesystem use. This is dangerous because local prompt/category files can meaningfully alter model behavior, yet that attack surface is not disclosed to the user or to a policy engine evaluating the skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
Loading local category definitions and prompts from disk while advertising a direct arXiv reading workflow creates a misleading trust boundary around filesystem use. This is dangerous because local prompt/category files can meaningfully alter model behavior, yet that attack surface is not disclosed to the user or to a policy engine evaluating the skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
Loading local category definitions and prompts from disk while advertising a direct arXiv reading workflow creates a misleading trust boundary around filesystem use. This is dangerous because local prompt/category files can meaningfully alter model behavior, yet that attack surface is not disclosed to the user or to a policy engine evaluating the skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Loading local category definitions and prompts from disk while advertising a direct arXiv reading workflow creates a misleading trust boundary around filesystem use. This is dangerous because local prompt/category files can meaningfully alter model behavior, yet that attack surface is not disclosed to the user or to a policy engine evaluating the skill.

Credential Access

High
Category
Privilege Escalation
Content
"""
Global configuration module.
Loads all settings from .env file at project root.
"""

import os
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"""
Global configuration module.
Loads all settings from .env file at project root.
"""

import os
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# ── Project Root ──────────────────────────────────────────────
PROJECT_ROOT = Path(__file__).parent.resolve()
load_dotenv(PROJECT_ROOT / ".env")

# ── LLM ──────────────────────────────────────────────────────
LLM_BASE_URL = os.getenv("LLM_BASE_URL", "https://api.openai.com/v1")
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

External Transmission

Medium
Category
Data Exfiltration
Content
# ==========================================

# LLM Configuration (DeepSeek)
LLM_BASE_URL=https://api.deepseek.com/v1
LLM_API_KEY=
LLM_MODEL=deepseek-chat
LLM_TEMPERATURE=0.6
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill declares access to environment variables and its documentation instructs installation and execution of Python code that also implies filesystem and network use, but it does not declare any explicit tool scope or permissions boundary. This is dangerous because users and orchestrators cannot easily understand or constrain what the skill may access, increasing the chance of over-privileged execution and unintended data exposure.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The description is written to indicate the skill will classify and deeply read the paper and directly print reading notes in Chinese, but it does not state that output language is configurable or user-selectable. This creates a natural-language locale policy concern because the skill appears to impose a specific language without opt-in.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The user-facing prompt text is written entirely in Chinese, which forces a specific language/locale for classification requests. The file does not offer a language choice or explain a justified region-specific constraint, matching the natural-language locale policy violation criteria.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The skill constructs its user-facing prompt entirely in Chinese and also returns Chinese fallback/error text. This enforces a specific language/locale behavior without any visible user choice or documented opt-in, which matches the natural-language policy violation criteria.

Description-Behavior Mismatch

Medium
Confidence
91% confidence
Finding
The manifest describes a skill that takes a specified arxiv_id or URL and deeply reads that paper, printing notes. In contrast, this file implements bulk discovery of recent papers across configured categories via RSS and API fallback, which is a broader paper-harvesting capability not implied by the stated single-paper reader purpose.

External Transmission

Medium
Category
Data Exfiltration
Content
load_dotenv(PROJECT_ROOT / ".env")

# ── LLM ──────────────────────────────────────────────────────
LLM_BASE_URL = os.getenv("LLM_BASE_URL", "https://api.openai.com/v1")
LLM_API_KEY = os.getenv("LLM_API_KEY", "")
LLM_MODEL = os.getenv("LLM_MODEL", "gpt-4o")
LLM_TEMPERATURE = float(os.getenv("LLM_TEMPERATURE", "0.3"))
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The entire prompt is written in Chinese and instructs the model in a single language without indicating that the user can choose another language or that the skill is intentionally region-specific. This is a natural-language locale policy concern because it imposes a language constraint by default.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The prompt text is entirely in Chinese and instructs the agent in Chinese, which implies a fixed output language/locale. There is no indication that the user can opt into another language or that the Chinese-only constraint is required for a region-specific or compliance-related purpose.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
Line L08 explicitly requires all output to be in Chinese. This is a natural-language locale policy constraint, and the file does not indicate user opt-in or a region-specific justification for forcing that language.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The instruction "你的输出语言为中文" mandates a specific language with no indication that the user can choose another language. Per the policy, forcing a locale or language without opt-in is a natural-language policy violation unless clearly justified.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The metadata description and note are written in Chinese, which imposes a specific language on users/readers without any visible opt-in or explanation that this category is intentionally region- or locale-specific. Under the policy rules, language restrictions are only acceptable when users are given a choice or the locale constraint is clearly documented and justified.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The descriptive content is written in Chinese and does not indicate that other languages are supported or that Chinese is a required, justified locale for this skill. This can violate a language/locale policy when users are not given an explicit language choice or opt-in.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The prompt requires output in Chinese throughout the summary structure without indicating this is conditional on the user's requested language. This can override user preference, reduce usability, and in some environments cause downstream prompt/formatting mismatches, though it does not directly enable code execution or data exfiltration.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The metadata description is written entirely in Chinese, which imposes a specific language on users without offering a language choice or explaining that the skill is intended only for a Chinese-language audience. Under the stated policy, forcing a specific language without opt-in is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The file’s descriptive content is written in Chinese, which imposes a specific language/locale in the skill metadata without offering user choice or documenting a justified region-specific constraint. Under the stated policy, forcing a specific language without opt-in is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This markdown file is entirely written as an instruction set in Chinese and directs the user to structure notes accordingly, which implicitly enforces a specific language/locale. Under the policy, forcing a language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified or optional.

Static analysis

No suspicious patterns detected.