Back to skill

Security audit

Zotero Vectorize

Security checks for vulnerabilities and agentic risk

Overview

This skill builds a local Zotero semantic index as advertised, with privacy and reliability cautions but no hidden or malicious behavior found.

Install only if you are comfortable letting the skill read your Zotero database and PDF attachment folder and store derived metadata, embeddings, and PDF text chunks in local JSON files. Use a virtual environment, consider pinning dependencies yourself, keep backups of existing vector-store outputs before full rebuilds, and avoid unusual chunk or batch-size arguments.

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)

T08 · Insecure Dependencies

Warning
Location
references/windows.md:31
Finding

Unpinned Third-Party Dependencies Create a Supply-Chain Risk

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/build_metadata_vectors.py:94
Finding

Full Rebuild Commands Overwrite Existing Vector Stores Without Backups or Atomic Writes

Content
View full analysis
None: path.parent.mkdir(parents=True, exist_ok=True) with path.open("w", encoding="utf-8") as f: json.dump(payload, f, ensure_ascii=False, indent=2) f.write("\n") ``` ### Technical Analysis The incremental updater calls `backup_store_files()` before rewriting output files, but the two full-rebuild scripts do not. Both rebuild scripts directly invoke `save_json()` on the final destination. Opening an existing destination with mode `"w"` truncates it before serialization finishes. If the process is interrupted by a crash, power loss, disk exhaustion, serialization error, or forced termination, the destination may be left empty or partially written. Because the rebuild paths do not first create the documented backups, the ...[truncated 1321 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/zotero_vectorize_lib.py:487
Finding

Unvalidated Chunking Parameters Can Cause an Infinite Loop and Resource Exhaustion

Content
View full analysis
list[dict]: words = text.split() if not words: return [] if len(words) <= chunk_size: return [{"text": text, "word_count": len(words), "start_word": 0, "end_word": len(words)}] chunks = [] start = 0 while start < len(words): end = min(start + chunk_size, len(words)) chunk_words = words[start:end] chunks.append( { "text": " ".join(chunk_words), "word_count": len(chunk_words), "start_word": start, "end_word": end, } ) start = end - overlap if start >= len(words) - overlap: if start < len(words): remainder = words[start:] chunks.append( { "text": " ".join(remainder), "word_count": len(remainder), "start_word": start, "end_word": len(words), } ) break return chunks ``` ### Technical Analysis The implementation assumes all of the following invariants, but does not enforce them: - `chunk_size > 0` - `overlap >= 0` - `overlap < chunk_size ...[truncated 1709 chars]
Remediation
View remediation
= args.chunk_size: parser.error("--chunk-overlap must be smaller than --chunk-size") if args.batch_size <= 0: parser.error("--batch-size must be greater than zero") ``` 2. Apply equivalent positive-value validation to both metadata and full-text batch-size arguments in all entry points. 3. Enforce the same invariants inside `chunk_text()` so direct library callers cannot bypass CLI validation. 4. Replace the update logic with an explicitly positive step: ```python step = chunk_size - overlap if step <= 0: raise ValueError("chunk_size must be greater than overlap") ``` 5. Add unit tests for zero, negative, equal, and oversized overlap values. 6. Add a defensive upper limit for chunk size and batch size to reduce accidental memory exhaustion. ]]>
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
94% confidence
Finding

The declared description centers on vectorizing a Zotero library and maintaining semantic/RAG index files such as metadata_vectors.json and fulltext_vectors.json. This code chunk instead serves a different purpose: making a filesystem snapshot of the Zotero SQLite database. While snapshotting could be a supporting step in a larger indexing workflow, this specific script's primary behavior is backup/copy creation of the database, which is not described. It also does not itself perform any embedding, vector store maintenance, or verification tasks named in the description. Therefore the code chunk is a material mismatch with the declared purpose.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Keep `SKILL.md` focused on workflow. Read the reference files only when needed:

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The library extracts full text from local PDF attachments and is designed to persist chunked embeddings/store outputs, but this file provides no user-facing consent, sensitivity checks, or warning that potentially confidential document contents will be processed and stored. In the context of a Zotero semantic indexer, that creates a real privacy/security risk because research papers, drafts, legal/medical documents, or licensed content may be silently copied into derived local artifacts that broaden exposure and retention.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
78% confidence
Finding

The code loads a sentence-transformers model and encodes supplied texts, which are built elsewhere from Zotero metadata and PDF full text. Because model loading can involve network access and users are not warned here that their library content may be processed by an external model stack, this safety-relevant behavior lacks visible disclosure in the code file.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.