Back to skill

Security audit

Literature Review

Security checks for vulnerabilities and agentic risk

Overview

This is mostly a legitimate literature-review helper, but it uses broad local command authority and includes an unsafe PDF-generation path that should be reviewed before installation.

Install only if you are comfortable granting local file and command execution authority. Use it in a dedicated workspace or container, avoid running PDF generation on untrusted filenames or documents, pin dependencies, and treat the English/prestige-based review guidance as optional rather than systematic-review policy.

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
scripts/generate_pdf.py:31
Finding
Pandoc Option Injection Through an Attacker-Controlled Input Filename## Vulnerability Details **File Location**: `scripts/generate_pdf.py`, lines 31-91 **Vulnerability Type**: Pandoc argument and option injection **Risk Level**: Medium ### Vulnerable Code ```python # Verify markdown file exists if not os.path.exists(markdown_file): print(f"Error: Markdown file not found: {markdown_file}") return False # Set default output path if output_pdf is None: output_pdf = Path(markdown_file).with_suffix('.pdf') # Build pandoc command cmd = [ 'pandoc', markdown_file, '-o', str(output_pdf), '--pdf-engine=xelatex', '-V', 'geometry:margin=1in', '-V', 'fontsize=11pt', '-V', 'colorlinks=true', '-V', 'linkcolor=blue', '-V', 'urlcolor=blue', '-V', 'citecolor=blue', ] # Execute pandoc try: print(f"Generating PDF: {output_pdf}") print(f"Command: {' '.join(cmd)}") result = subprocess.run(cmd, capture_output=True, text=True, check=True) ``` ### Technical Analysis The Markdown filename is supplied through the command line and passed directly to Pandoc before an option terminator. Although `subprocess.run()` uses an argument array and therefore prevents shell metacharacter injection, it does not prevent option injection into Pandoc itself. A valid local filename beginning with a hyphen can be interpreted as a Pandoc command-line option rather than as an input filename. For example, a filename such as `--lua-filter=payload.lua` could cause Pandoc to load a Lua filter. Pandoc Lua filters can execute local operations with the privileges of the process running Pandoc. The existing `os.path.exists(markdown_file)` check only establishes that a filesystem entry with the supplied name exists. It does not establish that Pandoc will treat the value as a positional input file. ### Attack Path 1. An attacker gains the ability to create or supply files in the working directory used by the script. 2. The attacker creates a malicious Pandoc Lua filter, such as `payload.lua`. 3. The attacker cr ...[truncated 1428 chars]
Remediation
## Remediation Suggestions 1. Resolve the input to a normalized absolute path before passing it to Pandoc: ```python input_path = Path(markdown_file).resolve(strict=True) if not input_path.is_file(): print(f"Error: Markdown input is not a regular file: {input_path}") return False ``` 2. Pass only the normalized absolute path to Pandoc. On POSIX systems, an absolute path starts with `/` and therefore cannot be interpreted as a command-line option. 3. Where supported by the target Pandoc version, insert an option terminator before positional input paths: ```python cmd = [ "pandoc", "-o", str(output_path), "--pdf-engine=xelatex", "-V", "geometry:margin=1in", "-V", "fontsize=11pt", "-V", "colorlinks=true", "-V", "linkcolor=blue", "-V", "urlcolor=blue", "-V", "citecolor=blue", "--", str(input_path), ] ``` 4. Apply equivalent normalization and regular-file validation to the output path, bibliography, CSL file, and template path. 5. If inputs are expected to reside in a controlled workspace, enforce that the resolved path remains under that directory using `Path.is_relative_to()` or an equivalent containment check. 6. Add regression tests using filenames beginning with `-`, including names that resemble `--lua-filter`, `--filter`, `--template`, and other Pandoc options. 7. Run document conversion in a restricted container or sandbox with no secrets, minimal filesystem access, no unnecessary network access, and a non-privileged user.

T08 · Insecure Dependencies

Note
Location
SKILL.md:602
Finding
Unpinned Third-Party Dependency Installation## Vulnerability Details **File Location**: `SKILL.md`, lines 602-606 **Vulnerability Type**: Unpinned and non-reproducible dependency installation **Risk Level**: Low ### Vulnerable Code ```markdown ### Required Python Packages ```bash pip install requests # For citation verification ``` ``` ### Technical Analysis The installation instruction retrieves the latest version of `requests` and its transitive dependencies from the package index configured for `pip`. It does not specify reviewed versions, artifact hashes, a lockfile, an isolated environment, or an approved package source. The referenced package name is legitimate, and the project does not specify a suspicious external package repository. Therefore, this is not evidence that a malicious dependency was intentionally introduced. It is nevertheless an insecure supply-chain practice because the effective code installed can change over time without any change to the audited project. The risk also extends to transitive dependencies resolved by `pip`. A compromised release, compromised package-index account, maliciously configured package mirror, or future incompatible release could introduce unwanted code into the environment. ### Attack Path 1. A user follows the documented prerequisite command: ```bash pip install requests ``` 2. `pip` contacts its configured package index or mirror and resolves the latest eligible release of `requests` and its transitive dependencies. 3. If an upstream account, release artifact, dependency, or configured mirror has been compromised, `pip` downloads the affected package. 4. Package installation hooks or subsequently imported malicious code execute with the permissions of the user performing the installation or running `verify_citations.py`. This path requires a supply-chain compromise or an attacker-controlled package source; the audited repository itself does not redirect installation to an identified malicious source. ### Impact Assessment A compr ...[truncated 520 chars]
Remediation
## Remediation Suggestions 1. Add a reviewed dependency file with exact versions rather than instructing users to install a mutable latest release: ```text requests==2.32.5 ``` 2. Pin all transitive dependencies through a generated lockfile. Tools such as `pip-tools`, Poetry, or `uv` can produce deterministic dependency sets. 3. Record and verify package hashes: ```text requests==2.32.5 \ --hash=sha256:REVIEWED_ARTIFACT_HASH ``` Install with: ```bash python -m pip install --require-hashes -r requirements.txt ``` 4. Generate hashes from reviewed artifacts rather than copying an unverified value. Update dependencies through a documented review and testing process. 5. Install dependencies inside a dedicated virtual environment or restricted container, not into the system Python environment: ```bash python -m venv .venv . .venv/bin/activate python -m pip install --require-hashes -r requirements.txt ``` 6. Document an approved package index and avoid untrusted mirrors or extra indexes that could enable dependency confusion. 7. Add automated vulnerability and integrity checks for the locked dependency set, while ensuring updates remain subject to human review.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • 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
Findings (13)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
This code chunk does not implement the core declared functionality of conducting comprehensive literature reviews across multiple databases. It has a much narrower purpose: generating PDFs from markdown files via pandoc. While PDF creation and citation-style formatting are consistent with one small part of the description, the main declared capabilities—database searching, literature aggregation, systematic review support, and verified citation handling—are absent. Therefore the description materially overstates what this code actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared description overstates the skill's functionality. This script has a narrow, support-role purpose: it reads a local JSON results file and performs formatting and light analysis operations such as deduplication, ranking, year filtering, and summary generation. There is no code for querying external literature databases, orchestrating systematic searches, validating references, generating PDFs, or producing formatted citations in the listed styles. While the markdown/BibTeX formatting is related to literature handling, the primary declared capability—comprehensive database searching and review generation—is not implemented in this code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared description presents a broad literature review and evidence-synthesis skill with multi-database search and document-generation capabilities. The supplied code does not implement literature retrieval, screening, synthesis, or PDF/markdown generation. Its actual function is much narrower: verifying DOI-based citations already present in a markdown file, retrieving CrossRef metadata, formatting a couple of citation styles, and saving a JSON report. While citation verification could be a supporting component of a literature-review tool, this code chunk by itself materially differs from the declared primary purpose and omits most of the advertised capabilities.

Lp1

High
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The script performs outbound network requests to doi.org and api.crossref.org, but the static finding indicates this capability is not declared in the skill's permissions. Undeclared network access is dangerous because it can silently transmit user-provided citation content or metadata to external services, violating least-privilege expectations and making the skill harder to review and contain.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The instructions state 'Language (typically English, or specify multilingual)', which establishes English as the default language for review inclusion criteria. This is a natural-language locale preference that is presented without explicit user opt-in or a documented region-specific justification.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
Defaulting inclusion criteria to English without user opt-in or a documented justification can create language bias and materially distort review findings. In the context of a skill advertised for comprehensive and systematic reviews across scientific domains, this is especially risky because it may silently exclude relevant non-English evidence while presenting the output as complete.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The documentation template hard-codes an English-language filter, which operationalizes language bias and encourages users to reproduce it uncritically. Because templates strongly shape actual workflow behavior, this can lead to systematic exclusion of non-English studies in reviews that claim reproducibility and completeness.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
Marking citation-count and venue-prestige prioritization as 'CRITICAL' biases evidence selection away from systematic-review principles, which should emphasize predefined inclusion criteria and study quality rather than popularity or prestige. In this skill context, that can systematically skew literature reviews, omit relevant lower-citation or newer studies, and produce misleading research syntheses presented as comprehensive and verified.

Intent-Code Divergence

Medium
Confidence
94% confidence
Finding
Instructing users to prefer Tier-1 venues, high-h-index authors, and recognized field leaders conflicts with the stated goal of a comprehensive systematic review and introduces authority and prestige bias. In a literature-review skill, this is more dangerous than in a casual discovery tool because users may rely on it to produce evidence syntheses, meta-analyses, or decision-support documents that appear methodologically rigorous while being systematically distorted.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
# Check if pandoc is installed
    try:
        subprocess.run(['pandoc', '--version'], capture_output=True, check=True)
    except (subprocess.CalledProcessError, FileNotFoundError):
        print("Error: pandoc is not installed.")
        print("Install with: brew install pandoc (macOS) or apt-get install pandoc (Linux)")
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
try:
        print(f"Generating PDF: {output_pdf}")
        print(f"Command: {' '.join(cmd)}")
        result = subprocess.run(cmd, capture_output=True, text=True, check=True)
        print(f"✓ PDF generated successfully: {output_pdf}")
        return True
    except subprocess.CalledProcessError as e:
Confidence
78% confidence
Finding
The script executes `pandoc` on user-controlled files and also passes user-influenced options such as `citation_style` and `template`. Although it avoids shell injection by using an argument list, invoking a powerful document converter on attacker-supplied content can expose the host to unsafe file access, dangerous includes/templates, or exploitation of pandoc/LaTeX processing behavior, which is especially relevant in a skill that processes externally sourced literature and citations.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
missing = []
    for name, cmd in dependencies.items():
        try:
            subprocess.run(cmd.split(), capture_output=True, check=True)
            print(f"✓ {name} is installed")
        except (subprocess.CalledProcessError, FileNotFoundError):
            print(f"✗ {name} is NOT installed")
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

External Transmission

Medium
Category
Data Exfiltration
Content
def _get_crossref_metadata(self, doi: str) -> Dict:
        """Get metadata from CrossRef API."""
        try:
            url = f"https://api.crossref.org/works/{doi}"
            response = self.session.get(url, timeout=10)

            if response.status_code == 200:
Confidence
88% confidence
Finding
This code sends DOI values to CrossRef over the network to retrieve metadata. In context this is expected functionality for citation verification, but it is still an external data transmission path that may disclose document-derived identifiers or access patterns to a third party, which matters if the reviewed manuscript or bibliography is sensitive or unpublished.

Static analysis

No suspicious patterns detected.