Back to skill

Security audit

Contract Diff

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does contract comparison, but it can silently install unpinned Python packages at runtime while handling sensitive legal documents.

Review before installing in a work or legal-document environment. Prefer running it only in an isolated virtual environment or container, install reviewed dependencies yourself, and avoid using the helper scripts that copy hardcoded workspace files or print detailed contract text to logs.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T08 · Insecure Dependencies

Warning
Location
scripts/compare.py:17
Finding

Automatic Installation of Unpinned Dependencies at Runtime

Content
View full analysis

Vulnerability Details

File Location: scripts/compare.py, lines 17–24
Vulnerability Type: Unsafe runtime dependency installation
Risk Level: Medium

Vulnerable Code

python
# Try to import required libraries
def try_import(*packages):
    for pkg in packages:
        try:
            __import__(pkg)
        except ImportError:
            os.system(f'pip install {pkg} -q')

try_import('python-docx', 'PyMuPDF', 'PIL', 'pytesseract')

Technical Analysis

The script automatically invokes pip install when an import attempt fails. Package versions and artifact hashes are not pinned, so the code installed and executed depends on the current state of the configured Python package index and dependency resolution process.

Python package installation can execute package build logic and may introduce executable modules that are subsequently imported by the application. Consequently, compromise of a named package, one of its transitive dependencies, the configured package repository, or the package-resolution path could result in arbitrary code execution under the account running the Skill.

The package names are also used incorrectly as import names in several cases. For example, the distribution python-docx is normally imported as docx, and PyMuPDF is commonly imported as fitz or pymupdf. These mismatches can cause failed import checks and unnecessary repeated installation attempts.

Although the package names in this particular call are fixed constants rather than user input, using os.system for dependency management unnecessarily invokes a shell and makes the installation process less controlled and auditable. The audit found no evidence that the project intentionally supplies a malicious package or exfiltrates data; the risk is the insecure, mutable dependency retrieval mechanism.

Attack Path

  1. A user invokes scripts/compare.py to compare contract files.
  2. One of the import checks fails, including potentially bec ...[truncated 1222 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove all automatic package installation from runtime application code.
  2. Declare dependencies in a dedicated dependency file and pin exact reviewed versions, for example:
    text
    python-docx==<reviewed-version>
    PyMuPDF==<reviewed-version>
    Pillow==<reviewed-version>
    pytesseract==<reviewed-version>
    
  3. Generate and enforce cryptographic hashes using a lockfile or pip install --require-hashes.
  4. Install dependencies during a controlled deployment step inside an isolated virtual environment or container.
  5. Configure deployments to use a trusted package index and restrict fallback to unapproved public or private indexes.
  6. Use correct module names solely for availability checks:
    python
    required_modules = ("docx", "fitz", "PIL", "pytesseract")
    
  7. If a dependency is absent, terminate with a clear error rather than modifying the environment:
    python
    import importlib.util
    
    missing = [
        name for name in required_modules
        if importlib.util.find_spec(name) is None
    ]
    if missing:
        raise RuntimeError(
            "Missing required modules: " + ", ".join(missing)
        )
    
  8. Add dependency vulnerability scanning and periodic review of direct and transitive dependencies to the release process.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

This code chunk only prepares input files by enumerating a local directory and renaming/copying one DOCX and one PDF to fixed filenames. That may be a supporting preprocessing step for a larger contract-diff system, but on its own it does not carry out the declared primary purpose of comparing contracts and producing a Word report of differences. Because the actual behavior is materially narrower and different from the declared skill behavior, this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The core purpose broadly aligns: the script compares a template DOCX with a stamped PDF and identifies text differences/additions/modifications. However, the declared description specifically says the output is a Word document for easy download, while the code only prints results to standard output and never creates a .docx report. It also uses hardcoded input filenames rather than implementing a general-purpose skill interface. These are material differences in behavior, so this should be flagged as a mismatch.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Automatic package installation is outside the stated purpose of comparing contracts and introduces arbitrary third-party code execution into a workflow that may process sensitive legal documents. Because the skill may run in enterprise or agent environments, this behavior materially increases risk by allowing network access and environment mutation during normal use.

Content

No source excerpt is available for this finding.

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
98% confidence
Finding

The script executes a shell command to install Python packages at runtime via os.system. Even though the package names are hardcoded, this enables unreviewed code download and execution from package repositories, creates supply-chain exposure, and violates least surprise for a document-processing skill that should not modify the host environment.

Content

Scanner excerpt · scripts/compare.py (reported line 22)May include surrounding context.

python
try:
            __import__(pkg)
        except ImportError:
            os.system(f'pip install {pkg} -q')

try_import('python-docx', 'PyMuPDF', 'PIL', 'pytesseract')

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill documentation instructs use of file reads, file writes, package installation, and shell execution, but it does not declare any explicit tool scope or permissions boundaries. In an agent environment, this increases the chance of over-broad tool access, unintended filesystem modification, or execution of commands beyond what is necessary for document comparison.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The sample report format is entirely in Chinese, including headings and warnings, which implies the skill may force Chinese-language output. The file does not offer a user language choice or justify a Chinese-only locale, creating a natural-language policy concern.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest describes a skill that compares a template and a signed contract and outputs differences as a Word document. This file additionally performs filesystem mutation inside the input directory by copying discovered files to fixed names, which goes beyond the described comparison behavior and changes the user's workspace state.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Installing packages automatically without clear warning or confirmation is dangerous because it changes the host environment and may fetch and run external code unexpectedly. In a skill handling potentially sensitive contracts, silent dependency installation undermines operator trust and can expose systems to supply-chain or policy-compliance issues.

Content

No source excerpt is available for this finding.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Confidence
93% confidence
Finding

The code performs dynamic imports and then couples import failure to a shell-based package installation path. While the listed package names are hardcoded and not directly user-controlled here, dynamic import plus fallback execution expands the attack surface and can load unexpected modules or trigger unsafe runtime behavior in unpinned environments. In a contract-comparison skill, runtime dependency resolution is unnecessary and increases supply-chain risk.

Content

Scanner excerpt · scripts/compare.py (reported line 20)May include surrounding context.

python
def try_import(*packages):
    for pkg in packages:
        try:
            __import__(pkg)
        except ImportError:
            os.system(f'pip install {pkg} -q')

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The OCR calls hard-code lang='chi_sim+eng', which imposes a specific language/locale behavior on all users. The file does not offer a language option or explain that the tool is intentionally limited to Chinese and English documents, which matches the policy-violation criterion for forced language/locale behavior without opt-in.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script prints extracted contract differences directly to stdout instead of producing the promised Word document. In an agent or automation environment, stdout is commonly logged, surfaced in chat, or stored in task traces, which can unintentionally expose sensitive contract text, signatures, pricing terms, or legal clauses to unintended parties.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

This markdown report forces a specific language/locale for the skill output, as all headings, labels, and warnings are written in Chinese with no indication that users can opt into another language. The stated policy flags language or locale restrictions unless the skill offers user choice or clearly documents a justified regional constraint.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The manifest says the skill outputs differences as a Word document for easy download. The script documentation and implementation explicitly support Markdown output as an alternate report format, which is broader behavior than the manifest describes.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The manifest specifically describes comparing a template with a scanned stamped contract. This implementation simply calls PDF text extraction on the stamped file and does not include OCR or other handling typically required for scanned-image contracts, so the actual behavior is narrower than the stated purpose.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.