Back to skill

Security audit

Release20260324

Security checks for vulnerabilities and agentic risk

Overview

This academic paper tool is mostly purpose-aligned, but it needs review because its browser server is exposed more broadly than described and some PDF text can be sent to external LLM providers automatically.

Install only if you are comfortable with a networked academic-research tool that can call scholarly APIs, use API keys from your environment, modify graph JSON files, and run a browser management server. Avoid serve mode on untrusted networks, work on copies of graph files, do not process confidential PDFs with LLM keys configured unless you intend to send snippets to that provider, and review or pin dependencies before running the installer.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (6)

T09 · Insecure Skill Coding Practices

Error
Location
services/html_export.py:361
Finding

Stored Script Injection in Exported and Served Citation Graphs

Content
View full analysis
"GraphData": with open(path) as f: data = json.load(f) paper_fields = {f.name for f in Paper.__dataclass_fields__.values()} nodes = [] for n in data.get("nodes", []): filtered = {k: v for k, v in n.items() if k in paper_fields} nodes.append(Paper(**filtered)) ``` ### Technical Analysis `json.dumps()` produces valid JSON but does not make that JSON safe for direct inclusion in an HTML `` sequence terminates the script element even when it occurs inside a JavaScript string. An attacker-controlled paper title, abstract, author, identifier, source, or pre-generated summary containing a closing script tag can therefore escape the generated data structure and inject a new script element. Relevant data can originate from ...[truncated 1473 chars]
Remediation
View remediation
` as `\u003e` - `&` as `\u0026` - U+2028 as `\u2028` - U+2029 as `\u2029` 3. Prefer placing serialized data in a non-executable element: ```html ``` Then read and parse its `textContent`. The JSON still must escape `<` to prevent `` termination. 4. Apply the same safe serializer to paper data, nodes, edges, classifications, seed identifiers, distributions, and pre-generated summaries. 5. Add a restrictive Content Security Policy that disallows inline and untrusted scripts. Use nonces or hashes where inline scripts remain necessary. 6. Add regression tests using values containing ``, HTML tags, quotes, U+2028, and U+2029. 7. Treat metadata from scholarly APIs, PDFs, BibTeX, Zotero, and imported graph files as untrusted. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
services/graph_server.py:783
Finding

Unauthenticated Graph-Management Server Exposed on All Network Interfaces

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
services/paper_downloader.py:126
Finding

Server-Side Request Forgery Through Unrestricted PDF URLs

Content
View full analysis
bool: if not url: return False if not any(hint in url.lower() for hint in ['.pdf', '/pdf/', 'pdf?', 'fulltext']): return False try: with httpx.Client(timeout=60, follow_redirects=True) as client: resp = client.get(url) if resp.status_code == 200 and len(resp.content) > 1000: if resp.content[:4] == b'%PDF': with open(dest, "wb") as f: f.write(resp.content) return True ``` Both the general URL and dedicated PDF URL fields are accepted: ```python if paper.url: if _download_from_url(paper.url, dest): return dest pdf_url = getattr(paper, 'pdf_url', None) if pdf_url: if _download_from_url(pdf_url, dest): return dest ``` Seed expansion invokes the downloader: ```python from services.paper_downloader import download_pdf pdf_path = download_pdf(paper) ``` ### Technical Analysis The downloader accepts URLs from graph records and external API metadata without validating: - URL scheme. - Destination hostname. - Resolved IP address. - Loopback, private, link-local, multicast, or reserved address r ...[truncated 1785 chars]
Remediation
View remediation

other

Warning
Location
services/graph_manager.py:540
Finding

Automatic Transmission of PDF Content to External LLM Providers Without Task-Specific Consent

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
services/graph_server.py:267
Finding

Unbounded HTTP Request and PDF Upload Handling Enables Denial of Service

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Unpinned Third-Party Dependencies Create Supply-Chain and Reproducibility Risk

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (85)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents an end-user research/literature-analysis skill, but the supplied code chunk does not implement those research features. Instead, it is an installation and environment-check script for setting up the skill. While such setup logic may support the skill, this chunk’s primary behavior is materially different from the declared purpose and includes undeclared system-modifying capabilities like pip installation, symlink creation, and deletion of existing install artifacts. Therefore this code chunk does not accurately represent the declared behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

This code chunk does not implement literature discovery, citation network construction, PDF parsing, Zotero import, export formats, graph visualization, or multi-source scholarly search. Instead, its primary purpose is infrastructure for calling external language models across many providers. While an LLM client could support downstream research-summary features, the chunk itself is a generic AI backend utility and introduces undeclared external model-calling capability. That is a materially different purpose from the declared academic search/citation-analysis functionality, so this is a clear description-behavior mismatch.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
75% confidence
Finding

The skill uses 'env' capability that is not listed in its permissions. This may indicate deceptive intent or missing permission declarations.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
75% confidence
Finding

The skill uses 'network' capability that is not listed in its permissions. This may indicate deceptive intent or missing permission declarations.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · install.sh (reported line 132)May include surrounding context.

sh
# Remove old installation (copy or broken symlink)
    if [ -e "$target_dir/SKILL.md" ] || [ -L "$target_dir/SKILL.md" ]; then
        rm -f "$target_dir/SKILL.md"
        info "Removed old installation"
    fi
    # Also remove legacy flat file if it exists

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · install.sh (reported line 137)May include surrounding context.

sh
fi
    # Also remove legacy flat file if it exists
    if [ -e "$HOME/.claude/commands/opg.md" ] || [ -L "$HOME/.claude/commands/opg.md" ]; then
        rm -f "$HOME/.claude/commands/opg.md"
        info "Removed legacy opg.md"
    fi

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The README states that all graph mutations are saved to the JSON file immediately, but does not prominently warn users before they enter a persistent editing workflow. In an agent-assisted context, users may assume exploration is ephemeral; silent persistence can lead to accidental overwrites, unintended retention of sensitive research data, or corruption of curated graph files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README states that graph edits are immediately persisted to the JSON file and that all operations auto-save, but it does not prominently warn users before destructive or state-changing actions. In an agent skill context, natural-language invocation and automation increase the chance of unintended file modification or data loss, especially if an agent launches serve or performs add/remove/enrich actions on user files without explicit confirmation.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding

Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding

Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest says to use the skill when the user asks about 'finding papers, literature review, citation analysis, research trends, or visualizing citation networks.' Several of these phrases, especially 'literature review' and 'research trends,' are broad everyday research requests without clear boundaries on when this skill should or should not activate.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill exposes a persistent local HTTP server that can modify graph JSON files through a browser, which increases attack surface beyond simple local CLI use. Even when bound locally, a browser-accessible mutating interface can enable unintended file changes, cross-origin/browser-triggered requests, or misuse by other local processes if no authentication, origin checks, or explicit safety constraints exist.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill documents persistent file modifications and a local mutating server without an explicit warning, which can lead users to invoke behavior with state-changing side effects they do not expect. In an agent context, insufficient disclosure around persistence and browser-accessible mutation raises the risk of unintentional local data alteration.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The graph-removal commands overwrite files and remove data, yet the skill text lacks a clear safety warning or strong guardrails around destructive use. In an agent-driven environment, omission of explicit destructive-operation warnings can cause accidental loss of local work when commands are selected automatically from a high-level request.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The code extracts text from user-supplied PDFs and sends up to 12,000 characters to an LLM service for reference extraction without an explicit consent or warning at the call site. Academic PDFs may contain unpublished, licensed, or sensitive material, so transmitting their contents to a third-party model can create privacy, confidentiality, and compliance risks.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The function reads S2_API_KEY from the environment and uses it in outbound HTTP requests, which qualifies as sensitive credential access combined with network transmission. Although the code logs enrichment progress, it does not visibly warn the user that an API credential from the environment will be used for remote requests.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

This code path performs HTTP GET requests to Semantic Scholar using headers derived from S2_API_KEY, accessing a sensitive environment variable and transmitting request data externally. The existing stderr progress messages do not clearly disclose the credential usage or external network behavior to the user in a safety-warning sense.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code removes existing global installation files and replaces them with a symlink, which modifies user configuration under ~/.claude. Although the script prints progress messages, it does not clearly warn the user beforehand that an existing installation will be deleted/replaced, making the destructive behavior insufficiently disclosed.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest describes literature discovery, citation analysis, importing, summarizing, exporting, and visualization, but this file also adds an interactive management server and graph-editing commands that modify stored graph data. Those are materially different operational capabilities from read/analyze/export workflows and are not reflected in the stated skill description.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest focuses on research discovery and citation-network processing, but cmd_serve starts an interactive server for graph management. Hosting a local server is a distinct runtime behavior not mentioned in the manifest and changes the skill from a CLI data tool into a service endpoint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The remove-seed command saves changes to args.output or, by default, overwrites the original graph file in place without any confirmation, backup, or dry-run behavior. In an agent context, this can cause silent destructive modification of user research data if the command is invoked with an ambiguous title match or unintended target.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The remove-paper command also defaults to writing back to the original graph file, making deletions destructive by default. Because the command supports fuzzy title substring matching before deletion, an operator or agent could remove the wrong paper and persist the loss immediately, increasing the risk of accidental data corruption.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

For a skill presented as academic literature discovery and citation analysis, opening a management server is not an obvious required capability in the same way that search, PDF parsing, or export are. This introduces a service-hosting behavior that is qualitatively different from the manifest’s research-assistance focus.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The LLM summarization path sends titles, authors, citation counts, years, and up to 300 characters of each abstract to an external LLM provider via llm_chat() when a provider is configured. In a literature-analysis skill, abstracts and metadata may include proprietary, unpublished, licensed, or otherwise sensitive research content, and this file provides no consent gate, redaction, or disclosure before off-box transmission.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code sends up to 3000 characters of first-page PDF content to an external LLM service for metadata extraction without any visible consent, disclosure, or data-minimization controls in this file. Academic PDFs can contain unpublished manuscripts, author emails, affiliations, or other sensitive content, so transmitting document text to a third-party model creates a real confidentiality and privacy risk, especially because this path is triggered automatically as a fallback when heuristic/API extraction fails.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.