Back to skill

Security audit

zotero-sholar

Security checks for vulnerabilities and agentic risk

Overview

This Zotero skill is mostly purpose-aligned, but its automatic PDF download and upload path is under-scoped and can fetch unintended URLs before uploading the result to Zotero.

Review this before installing. Use it only with Zotero API credentials you are comfortable granting write access to, and avoid running it on untrusted or user-supplied URLs until the arXiv URL handling is fixed with strict hostname validation, size/type checks, and explicit opt-in for PDF attachment upload.

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

Error
Location
scripts/save_paper.py:97
Finding

Insufficient URL Validation Enables Server-Side Request Forgery and Unintended Data Upload

Content
View full analysis
Remediation
View remediation
.pdf` internally. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/save_paper.py:2
Finding

Automatically Installed Dependency Is Not Reproducibly Pinned

Content
View full analysis
=3.10" # dependencies = ["pyzotero>=1.6.0"] # /// ``` The documented execution path in `SKILL.md` invokes the script through `uv run`, which automatically resolves and installs this dependency. ### Technical Analysis The dependency declaration uses the open-ended constraint `pyzotero>=1.6.0`. Consequently, future compatible releases can be downloaded and executed without being represented in the reviewed project contents. This makes installations non-reproducible and expands the trusted code base after the audit. If a future package release or transitive dependency is compromised, running the documented command can execute that changed package code with the same permissions and environment access as the Skill. The audit did not establish that the current `pyzotero` package is malicious. The finding concerns the unsafe, mutable dependency-resolution policy rather than confirmed malicious behavior in a specific package version. ### Attack Path 1. A user invokes the documented `uv run` command. 2. `uv` resolves `pyzotero` using the open-ended `>=1.6.0` constraint. 3. A newer package version or changed transitive dependency may be selected from the configured package index. 4. The resolved package is installed and imported by: ```python from pyzotero import zotero ``` 5. Package initialization or subsequently called package code executes with the Skill process's permissions. Exploitation depends on compromise of a future allowed release, a transitive dependency, or the configured package source. ### Impact Assessment A compromised dependency could execute arbitrary Python code with the privileges of the user running the Skill. It could access files readable by that user, make network requests, alter proce ...[truncated 249 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The documented purpose says the skill saves paper metadata and abstracts to Zotero, but the detected behavior also includes downloading PDFs from arXiv, uploading attachments to Zotero, and accessing external network resources beyond Zotero itself. This mismatch is dangerous because reviewers and users may approve the skill under a narrower trust model, while the actual behavior expands data transfer, network exposure, and attachment handling in ways that could leak data or fetch untrusted content.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill declares access to an environment secret and performs networked actions, but it does not define any explicit tool scope or permission boundaries. This increases the chance that an agent or runtime will grant broader-than-necessary capabilities, especially since the skill handles ZOTERO_CREDENTIALS and may contact external services.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The CLI description and argument help strings are presented only in Chinese, and the rest of the script's user-facing output follows the same pattern. This imposes a language choice on all users without opt-in or indication that the tool is intentionally limited to a Chinese-speaking context.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill behavior exceeds its stated scope by silently downloading a PDF from arXiv and uploading it to Zotero, while the manifest only describes saving papers and abstracts. This creates a transparency and consent problem: users may authorize metadata storage but not expect network retrieval of third-party content and attachment upload, which can have bandwidth, storage, and policy implications.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The code reads ZOTERO_CREDENTIALS from the environment and parses an API key, which is a sensitive credential access path. While the script prints an error when credentials are missing, it does not disclose to the user that it will read and use stored credentials for authenticated API actions.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.