Back to skill

Security audit

GLM-V-PDF-to-WEB

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its PDF-to-website purpose, but its URL downloading and crop output handling are under-scoped enough to warrant review before installation.

Review before installing. Prefer local PDFs or trusted URLs only, run it in a restricted workspace, install dependencies in a virtual environment with pinned versions, and patch the crop filename sanitization and temporary-file handling before using it on untrusted PDFs or shared machines.

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
SKILL.md:27
Finding

Unpinned Third-Party Dependencies Create Supply-Chain Risk

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, line 27
Vulnerability Type: Unpinned dependency installation
Risk Level: Medium

Vulnerable Code

bash
pip install pymupdf pillow

Technical Analysis

The documented installation command retrieves mutable package versions from the Python package index configured on the user's system. Neither exact versions nor cryptographic hashes are specified.

Python package installation may execute package build or installation logic. Consequently, a compromised package release, package repository, dependency, or maliciously configured package index could introduce arbitrary code during installation. The absence of a lock file also makes installations non-reproducible and allows future releases to alter the skill's effective dependency set without changes to the audited project.

No evidence indicates that pymupdf or pillow is currently malicious. The vulnerability is the unsafe and non-reproducible dependency acquisition process.

Attack Path

  1. An attacker compromises a dependency release, a transitive dependency, or a package index used by the victim.
  2. The victim follows the installation command from SKILL.md.
  3. pip resolves the affected mutable package version from the configured index.
  4. Package installation or build logic executes with the privileges of the user running pip.
  5. The malicious package can access data and resources available to that user.

Impact Assessment

Successful exploitation could result in arbitrary code execution with the privileges of the user installing the dependencies. This may expose user-readable files, environment variables, project data, and network-accessible services. If installation is performed with elevated privileges, the impact may extend to system-wide compromise.

Remediation
View remediation

Remediation Suggestions

  1. Pin all direct and transitive dependencies to reviewed versions in a lock file.
  2. Require cryptographic hashes during installation, for example with pip install --require-hashes -r requirements.txt.
  3. Generate and review dependency locks using a reproducible dependency-management process.
  4. Install dependencies in a dedicated virtual environment rather than the global Python environment.
  5. Use a trusted package index explicitly and monitor dependencies for reported vulnerabilities.
  6. Document a controlled dependency-update and security-review procedure.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/crop.py:57
Finding

Unsanitized Crop Name Permits Output Path Traversal

Content
View full analysis

Vulnerability Details

File Location: scripts/crop.py, lines 57–62
Vulnerability Type: Path traversal and arbitrary file overwrite
Risk Level: Medium

Vulnerable Code

python
stem = name or _safe_stem(img_path)
filename = f"{stem}_crop.png"
os.makedirs(out_dir, exist_ok=True)
out_path = os.path.join(out_dir, filename)

cropped.save(out_path, format="PNG")

The relevant command-line argument is accepted without validation at lines 80–82:

python
parser.add_argument(
    "--name", default=None, help="Output filename stem (default: derived from path)"
)

Technical Analysis

The helper _safe_stem() sanitizes a name derived from the source image only when the caller does not provide --name. A caller-supplied name is used directly when constructing the destination path.

Because os.path.join() does not constrain the result to out_dir, a value containing parent-directory components, such as ../../target, can escape the intended crop directory. An absolute value can also cause os.path.join() to discard out_dir entirely. Pillow subsequently writes a valid PNG to the resulting location.

The fixed _crop.png suffix limits target filenames but does not prevent traversal or overwrite of writable files having that suffix. The documented workflow also directs an agent to generate and pass crop names, increasing the importance of treating names as untrusted input.

Attack Path

  1. An attacker or untrusted workflow input influences the value passed to --name.
  2. The supplied value contains traversal components, such as ../../outside/target.
  3. The script constructs:
    text
    <out-dir>/../../outside/target_crop.png
    
  4. The operating system resolves the traversal outside the intended output directory.
  5. Pillow creates or overwrites the destination if the process has sufficient filesystem permissions.

Impact Assessment

An attacker can create or overwrite .png-suffixed files anywhere writable by ...[truncated 366 chars]

Remediation
View remediation

Remediation Suggestions

  1. Apply _safe_stem() to caller-provided names as well as generated names:
    python
    stem = _safe_stem(name) if name else _safe_stem(img_path)
    
  2. Prefer a strict allowlist such as ASCII letters, digits, underscores, and hyphens.
  3. Explicitly reject absolute paths, path separators, . components, and .. components.
  4. Resolve and validate the final path before writing:
    python
    base = os.path.realpath(out_dir)
    out_path = os.path.realpath(os.path.join(base, filename))
    if os.path.commonpath([base, out_path]) != base:
        raise ValueError("Output path escapes the output directory")
    
  5. Consider exclusive file creation or an explicit overwrite flag to avoid silently replacing existing files.
  6. Add tests covering absolute paths, ../ traversal, nested separators, and platform-specific path syntax.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:69
Finding

Predictable Shared Temporary File Enables Symlink and Collision Attacks

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 69–72
Vulnerability Type: Unsafe temporary-file handling
Risk Level: Medium

Vulnerable Code

bash
pdf_stem=$(basename "$ARGUMENTS" .pdf)
curl -L -o "/tmp/${pdf_stem}.pdf" "$ARGUMENTS"

Technical Analysis

A remotely supplied PDF is downloaded to a predictable pathname in the shared /tmp directory. The filename is based only on the URL basename, with no random component, private directory, ownership check, or symlink protection.

On a multi-user system, another local process can predict the pathname and pre-create a symbolic link at that location. curl -o may then follow the link and overwrite its target with downloaded content, subject to the victim's permissions. Independent skill executions using the same basename can also overwrite or consume one another's files, causing integrity failures and cross-job interference.

The URL-derived basename is quoted when passed to curl, so the recorded code does not demonstrate shell command injection. The finding concerns predictable shared temporary storage.

Attack Path

  1. An attacker observes or predicts that a URL ending in paper.pdf will be processed.
  2. The attacker pre-creates /tmp/paper.pdf as a symbolic link to a file writable by the victim, or arranges a competing file at that path.
  3. The victim executes the documented download command.
  4. curl writes the remote PDF through the predictable path.
  5. The linked target may be overwritten, or another concurrent conversion may receive attacker-selected or incorrect content.

Impact Assessment

A local attacker may overwrite files writable by the victim through a prepared symbolic link, limited by normal filesystem permissions and the ability to predict the temporary name. Concurrent runs may corrupt each other's input, disclose job contents to local users depending on system temporary-directory controls, or generate websites from the wrong PDF. The issue does n ...[truncated 82 chars]

Remediation
View remediation

Remediation Suggestions

  1. Create a private, randomly named temporary directory:
    bash
    tmp_dir=$(mktemp -d)
    chmod 700 "$tmp_dir"
    pdf_path="$tmp_dir/input.pdf"
    curl --fail --location --output "$pdf_path" "$ARGUMENTS"
    
  2. Register cleanup with a shell trap:
    bash
    trap 'rm -rf "$tmp_dir"' EXIT
    
  3. Do not derive security-sensitive temporary paths solely from user-controlled basenames.
  4. Avoid following pre-existing symbolic links and do not reuse existing temporary files.
  5. Use restrictive permissions and ensure temporary files are inaccessible to unrelated local users.
  6. Use a unique directory per execution to prevent collisions between concurrent jobs.
  7. Add --fail and appropriate timeout and size controls to curl so HTTP errors or unbounded downloads are not treated as valid PDFs.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description says the skill converts PDFs such as research papers or project documents into a polished single-page academic/project website and structured outline JSON. The supplied code does none of that. It only opens a local image, converts coordinate values into pixel bounds, crops the selected rectangle, saves a PNG locally, and prints the output path as JSON. There is a clear primary-purpose mismatch: image cropping is unrelated to PDF understanding, document outlining, or website generation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents the skill as an end-to-end PDF-to-website converter that can turn research/project PDFs into a polished single-page site and output a structured outline JSON. The supplied code chunk does not perform PDF parsing, content extraction, website generation logic, multilingual handling, or JSON outline creation. Its sole function is to save an already-generated HTML file by copying it to an output directory as index.html. While this may be a supporting step within a larger pipeline, the code chunk itself materially under-delivers relative to the declared primary purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared purpose describes a high-level PDF-to-website transformation skill that should create a single-page academic/project website and a structured outline JSON. The supplied code does something much narrower and materially different: it renders PDF pages to PNG images using PyMuPDF and prints metadata about those image files. There is no logic for extracting document structure, summarizing content, generating HTML/CSS/JS, or producing a website. Therefore the code does not accurately represent the declared description.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill instructs use of shell commands and file writes but declares no explicit tool restrictions. That increases the attack surface because a caller or downstream agent may permit broader capabilities than necessary, enabling unintended filesystem modification or command execution during processing.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The invocation guidance includes broad phrases like 'create a webpage' and 'project page' plus 'or any similar intent in Chinese or English,' which lacks clear boundaries for when the skill should or should not activate. This can overlap with common requests for ordinary webpage creation that are not specifically about converting a PDF into an academic site.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill performs network downloads from user-supplied URLs without an explicit user-facing warning, which can surprise users and bypass expected consent boundaries. In agent environments, silent external access is risky because it can leak metadata, access attacker-controlled hosts, and process hostile files.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The language policy says to match the PDF language and 'No mixing,' which forces a specific language behavior without user opt-in or choice. This is a natural-language locale policy constraint and is not presented as an optional or justified region-specific requirement.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

Allowing arbitrary HTTP/HTTPS downloads based on user input introduces server-side request forgery style risk and expands the trust boundary beyond local PDFs. An attacker could supply internal, sensitive, or unexpected URLs, causing the agent to fetch untrusted content or interact with internal network resources.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The curl-based download step adds network access that is not tightly constrained and can be abused to retrieve malicious or oversized files. This can expose the runtime to untrusted input, internal network probing, and resource exhaustion, especially because the fetched file is later passed into local processing scripts.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script prints its success message only in Chinese (已生成...论文主页) with no option to select another language. This is a natural-language locale policy issue because the file imposes a specific language on users without opt-in or justification.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.