Back to skill

Security audit

ComPDF Conversion CLI

Security checks for vulnerabilities and agentic risk

Overview

This converter appears purpose-built, but it deserves Review because it broadly forces routing and automatically relies on unpinned or unchecked proprietary downloads while handling potentially sensitive documents.

Review before installing, especially for private or regulated documents. Use a sandboxed virtual environment, pin and verify the ComPDFKitConversion package, pre-stage trusted license/model files where possible, restrict network access, and understand that trial usage is counted locally under the user's home directory.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:4
Finding

Forced Skill Routing and Priority Takeover

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
SKILL.md:34
Finding

Unpinned Third-Party SDK Installation and Execution

Content
View full analysis
Remediation
View remediation
\ --hash=sha256: ``` The actual version and hash must be generated from a vendor-authenticated, audited artifact rather than invented or inferred. ]]>

T08 · Insecure Dependencies

Error
Location
scripts/compdf_conversion_cli.py:318
Finding

Integrity-Unchecked Remote AI Model Is Automatically Downloaded and Loaded

Content
View full analysis
None: destination.parent.mkdir(parents=True, exist_ok=True) with urllib.request.urlopen(url, timeout=timeout) as response, destination.open("wb") as output: while True: chunk = response.read(1024 * 1024) if not chunk: break output.write(chunk) def get_document_ai_model_path(scripts_dir: Path) -> Path: override = os.getenv(DOCUMENT_AI_MODEL_ENV) if override: return Path(override) return scripts_dir / "documentai.model" def ensure_document_ai_model(scripts_dir: Path) -> Path: model_path = get_document_ai_model_path(scripts_dir) if model_path.is_file() and model_path.stat().st_size > 0: return model_path temp_path = model_path.with_suffix(model_path.suffix + ".part") last_error: Exception | None = None for attempt in range(len(DOCUMENT_AI_MODEL_RETRY_DELAYS) + 1): try: print(f"documentai.model not found, downloading from {DOCUMENT_AI_MODEL_URL}...", file=sys.stderr) if temp_path.exists(): temp_path.unlink() download_file(DOCUMENT_AI_MODEL_URL, temp_path) if not temp_path.is_file() or temp_path.stat().st_size == 0: raise RuntimeError("Downloaded documentai.model is empty") temp_path.replace(model_path) break except Exception as exc: last_error = exc if temp_path.exists(): ...[truncated 4124 chars]
Remediation
View remediation
" def verify_sha256(path: Path, expected: str) -> None: digest = hashlib.sha256() with path.open("rb") as source: for chunk in iter(lambda: source.read(1024 * 1024), b""): digest.update(chunk) if digest.hexdigest() != expected: raise RuntimeError("Downloaded model failed integrity verification") ``` The expected digest must come from an authenticated vendor release and must not be downloaded from the same unauthenticated update path without signature verification. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (12)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- The entry point is `SKILL.md`; helper scripts are placed in `scripts/`.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill declares no explicit tool scope or permission boundaries, yet the documentation clearly describes capabilities to read/write local files, inspect environment configuration, and perform network downloads. In an agent setting, this mismatch weakens policy enforcement and user awareness, increasing the chance the skill is invoked with broader authority than intended.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The 'MUST use for ANY PDF or image format conversion task' and priority-over-other-skills language is overly broad and can force selection of this skill in situations where a safer, more local, or more appropriate alternative exists. Because this skill also performs downloads and uses proprietary components, overbroad routing increases the blast radius of accidental invocation and surprise data handling.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill is presented as a local conversion workflow, but it automatically downloads a license file and a large AI model from external servers on first run. That creates an unexpected supply-chain and privacy boundary: users may process sensitive documents believing the task is local, while the skill initiates outbound network activity and depends on remote content that is not pinned or independently verified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill lacks a prominent upfront warning that first use will contact external servers to download license and model files, despite emphasizing local conversion. This omission undermines informed consent and can expose users in restricted, privacy-sensitive, or air-gapped environments to unexpected outbound traffic and policy violations.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill is presented as a local document conversion tool, but it silently introduces runtime network behavior to fetch a license and AI model. This expands the trust boundary, creates data egress/supply-chain risk, and may violate operator expectations in restricted or privacy-sensitive environments.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The code includes built-in network retrieval of external assets unrelated to the user's immediate file input, which increases attack surface beyond simple conversion. If the remote host, transport, or downloaded content is compromised, the tool may persist and trust attacker-influenced files locally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The tool automatically downloads and stores the Document AI model when OCR or AI layout is enabled, without strong upfront consent or integrity verification. In a skill expected to process potentially sensitive documents, silent dependency fetching is dangerous because it introduces hidden network communication and a persistent supply-chain dependency.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The code auto-downloads and creates license.xml locally if it is absent, without clear upfront disclosure or authenticity checks beyond whatever the SDK later does with the key. This is risky because it normalizes hidden network access and trusts remote content that directly affects application authorization behavior.

Content

No source excerpt is available for this finding.

Scope Creep

Low
Category
Excessive Agency
Confidence
70% confidence
Finding

Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Content

Scanner excerpt · License.txt (reported line 48)May include surrounding context.

text
------------------------------------------------------------------------

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.

IN NO EVENT SHALL PDF TECHNOLOGIES, INC. OR ITS AFFILIATES BE LIABLE FOR

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · scripts/compdf_conversion_cli.py (reported line 294)May include surrounding context.

python
def resolve_converter(format_name: str):
    method_name = get_converter_method_name(format_name)
    converter = getattr(CPDFConversion, method_name, None)
    if converter is None:
        raise RuntimeError(f"Current SDK does not provide converter method: {method_name}")
    return converter

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The stated purpose is converting PDFs and images between formats, but the implementation also creates and updates a hidden usage-tracking file under the user's home directory. This licensing telemetry/enforcement behavior is not part of the conversion capability described to the user.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.