Back to skill

Security audit

paper-reading

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a coherent paper-reading helper, but its PDF downloader can reach non-arXiv network locations despite presenting itself as arXiv-scoped.

Review this skill before installing if it will run in an environment with access to private networks or sensitive writable paths. Prefer using local PDFs or trusted arXiv URLs, run it in a constrained workspace, avoid privileged execution, and pin dependencies if you adopt it.

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 (3)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/fetch_pdf.py:30
Finding

Weak arXiv URL Validation Permits Arbitrary Network Retrieval

Content
View full analysis
bool: return bool(re.search(r'arxiv\.org', url, re.IGNORECASE)) ``` ```python def download_pdf(url: str, output: str) -> str: url = normalize_arxiv_pdf_url(url) print(f"Downloading from: {url}", file=sys.stderr) urllib.request.urlretrieve(url, output) return os.path.abspath(output) ``` ```python if source.startswith("http://") or source.startswith("https://"): if not is_arxiv_url(source): print(f"Error: Only arXiv URLs are supported. Got: {source}", file=sys.stderr) sys.exit(1) output = args.output if not output: match = re.search(r'arxiv\.org/(?:abs|pdf)/([\d.]+)', source) if match: arxiv_id = match.group(1).replace(".", "_") output = f"arxiv_{arxiv_id}.pdf" else: output = "paper.pdf" pdf_path = download_pdf(source, output) ``` ### Technical Analysis The URL allowlist is implemented as an unanchored regular-expression search over the entire URL string. It verifies only that the text `arxiv.org` appears somewhere; it does not parse the URL or confirm that the destination hostname is an approved arXiv host. For example, a URL such as the following passes the check even though its destination is not arXiv: ```text http://127.0.0.1:8080/resource?source=arxiv.org ``` The URL remains unchanged by `normalize_arxiv_pdf_url()` unless it contains a matching `arxiv.org/abs/` substring. It is then passed directly to `urllib.request.urlretrieve()`. Redirect destinations are not independently validated, and the downloaded response is not checked for an expected media type, PDF signature, or maximum size. This creates an arbitrary network-retrieval primitive and p ...[truncated 1612 chars]
Remediation
View remediation
` and `/pdf/` formats, then construct the final PDF URL internally. 6. Disable automatic redirects or validate the scheme, hostname, port, and path of every redirect destination. 7. Stream the response with explicit connection and read timeouts and enforce a maximum download size. 8. Confirm the expected content type and verify that the downloaded file begins with a valid PDF signature. 9. Write to a newly created file and refuse to overwrite an existing destination unless the user explicitly confirms it. 10. Where appropriate, block loopback, link-local, private, and other internal address ranges after DNS resolution as defense in depth. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/fetch_pdf.py:25
Finding

arXiv Search Uses Unauthenticated HTTP and Trusts the Returned Download URL

Content
View full analysis
Optional[str]: """Search arXiv by title and return the PDF URL of the most relevant result.""" params = urllib.parse.urlencode({ "search_query": f'ti:"{title}"', "max_results": "1", "sortBy": "relevance", "sortOrder": "descending", }) url = f"{ARXIV_API}?{params}" req = urllib.request.Request(url, headers={"User-Agent": "PaperReading/1.0"}) try: with urllib.request.urlopen(req, timeout=30) as resp: data = resp.read().decode("utf-8") except Exception as e: print(f"Error searching arXiv: {e}", file=sys.stderr) return None ns = {"atom": "http://www.w3.org/2005/Atom", "arxiv": "http://arxiv.org/schemas/atom"} root = ET.fromstring(data) entries = root.findall("atom:entry", ns) if not entries: print(f"No results found on arXiv for title: {title}", file=sys.stderr) return None entry = entries[0] # Try to find PDF link links = entry.findall("atom:link", ns) for link in links: if link.get("title") == "pdf": return link.get("href") ``` The returned URL is later downloaded without validating its scheme or hostname: ```python pdf_url = search_arxiv(source) if not pdf_url: print(f"Error: Could not find paper on arXiv: {source}", file=sys.stderr) sys.exit(1) print(f"Found: {pdf_url}", file=sys.stderr) output = args.output if not output: safe_title = re.sub(r'[^\w\s-]', '', source)[:50].strip().replace(" ", "_") output = f"{safe_title}.pdf" pdf_path = download_pdf(pdf_url, output) ``` ### Technical Analysis The arXiv API endpoint uses plaintext HTTP. Consequently, neither the aut ...[truncated 1792 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
SKILL.md:36
Finding

Unpinned Runtime Installation of a Third-Party PDF Dependency

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description promises a full paper-reading and note-generation skill, including summarization/analysis and standardized Chinese notes. The supplied code chunk performs only the acquisition stage: local path validation, arXiv title lookup, and PDF download, followed by printing the resolved file path. While PDF download and arXiv search are consistent with part of the description, the primary declared purpose centers on reading papers and generating notes, which this code does not do. Therefore, the description materially overstates the behavior of this code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description presents a higher-level paper reading and note-generation tool that can accept multiple input types (local PDF, arXiv URL, paper title) and produce structured Chinese notes. The supplied code chunk is much narrower: it is a local PDF text/table extractor CLI. Its primary purpose is extraction, not summarization or note generation. Several key declared capabilities are absent, including arXiv lookup/download and title-based retrieval. Additionally, the code has a minor undeclared capability of writing extracted text to an output file. This is a material description-behavior mismatch.

Content

No source excerpt is available for this finding.

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · references/mHC.md (reported line 29)May include surrounding context.

md
**动机:** HC 通过增加拓扑复杂度和残差流宽度提升了性能,且不显著增加 FLOPs。但随着模型规模增大,HC 暴露出了严重的稳定性问题。

<!-- 这是一张图片,ocr 内容为: -->
![](https://cdn.nlark.com/yuque/0/2026/png/57569306/1767535158747-34ab19e4-bec9-4f80-bb38-e36d876b77d9.png)

## 2. 核心问题 (Problem Statement)

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · references/mHC.md (reported line 29)May include surrounding context.

md
**动机:** HC 通过增加拓扑复杂度和残差流宽度提升了性能,且不显著增加 FLOPs。但随着模型规模增大,HC 暴露出了严重的稳定性问题。

<!-- 这是一张图片,ocr 内容为: -->
![](https://cdn.nlark.com/yuque/0/2026/png/57569306/1767535158747-34ab19e4-bec9-4f80-bb38-e36d876b77d9.png)

## 2. 核心问题 (Problem Statement)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill instructs downloading PDFs from arXiv and saving both PDFs and notes to user-specified absolute paths, which implies network access and file writes without any declared tool scope or permission boundaries. Missing scope declarations increase the chance of overprivileged execution, unintended filesystem modification, or SSRF-like/network misuse if the runtime grants broad defaults.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

An overly broad invocation description can cause the skill to trigger on generic research or summarization requests, unnecessarily activating network downloads and file-writing workflows. In context, this increases the risk of unintended data handling, surprise side effects, and execution in situations where the user did not clearly request external fetches or file output.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The description states that the skill will 'generate structured reading notes in Chinese,' imposing a specific language choice by default. There is no indication that the user may choose another language or opt into Chinese output.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The key requirements specify 'Language: Chinese with English technical terms preserved,' which is a hard language policy. Because no alternative language option or user opt-in is described, this conflicts with the requirement to avoid forcing a specific language unnecessarily.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The markdown explicitly requires notes to be primarily in Chinese ("中文为主") and does not present this as an optional or user-selectable preference. This is a natural-language locale constraint that can violate language-choice policy when not justified or opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

This markdown file presents all instructional and descriptive content in Chinese, and there is no indication that users can choose another language or that the document is intended only for a Chinese-language audience. Under the policy criteria, forcing a specific language without user opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.