Back to skill

Security audit

Image Duplication Detector

Security checks for vulnerabilities and agentic risk

Overview

The skill is a local manuscript image scanner with no evidence of exfiltration or persistence, but its install path uses ambiguous unpinned dependencies and some advertised analysis modes are broken or misleading.

Review before installing. Use a clean virtual environment, replace cv2 with opencv-python and pil with Pillow, pin audited dependency versions, and avoid running this on sensitive manuscripts unless you are comfortable with reports and temporary images being written locally. Treat tampering and PDF results as advisory because key workflows appear unreliable.

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
requirements.txt:1
Finding

Noncanonical and Unpinned Python Dependencies Create Supply-Chain Risk

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1-7; installation instructions at SKILL.md:156-160
Vulnerability Type: Dependency confusion, package-name ambiguity, and unrestricted dependency resolution
Risk Level: Medium

Vulnerable Code

requirements.txt:1-7:

text
cv2
dataclasses
imagehash
matplotlib
numpy
pdf2image
pil

SKILL.md:156-160:

bash
# Python dependencies
pip install -r requirements.txt

Technical Analysis

The dependency manifest uses the noncanonical package names cv2 and pil, while the application imports OpenCV and Pillow through cv2 and PIL. The established distribution names for these modules are opencv-python and Pillow, respectively. Import-module names are not necessarily valid or trustworthy distribution names.

The manifest also specifies no versions or integrity hashes. Consequently, installation resolves whichever releases the configured package index currently serves rather than a reproducible, previously reviewed dependency set. This creates supply-chain exposure to package-name confusion, compromised future releases, and unexpected compatibility or security regressions.

The project documentation lists minimum versions for several dependencies, but those constraints are not reflected in the actual requirements.txt used by the documented installation command. The dataclasses package is also generally unnecessary on supported Python versions where dataclasses is part of the standard library, increasing the dependency surface without a demonstrated need.

Attack Path

  1. A user follows the documented prerequisite command: pip install -r requirements.txt.
  2. pip resolves the ambiguous cv2 and pil names and the unrestricted latest versions of all other dependencies from the configured package index.
  3. An unintended package, maliciously published package, or compromised release is selected.
  4. Pac ...[truncated 1076 chars]
Remediation
View remediation

Remediation Suggestions

  1. Replace import-module names with the correct distribution names:
    • Replace cv2 with opencv-python.
    • Replace pil with Pillow.
  2. Remove dataclasses if the minimum supported Python version provides it in the standard library.
  3. Pin every direct and transitive dependency to a reviewed version through a lock file.
  4. Add cryptographic hashes and install with pip --require-hashes to prevent unreviewed artifacts from being substituted.
  5. Generate dependencies from a reviewed source manifest using a tool such as pip-tools, and update them through a controlled review process.
  6. Audit packages with a dependency scanner and install only from a trusted, explicitly configured package index.
  7. Keep SKILL.md and requirements.txt synchronized so the documented versions match the dependencies actually installed.

A corrected source manifest should begin with canonical, constrained package names, for example:

text
opencv-python==<reviewed-version>
imagehash==<reviewed-version>
matplotlib==<reviewed-version>
numpy==<reviewed-version>
pdf2image==<reviewed-version>
Pillow==<reviewed-version>

Exact versions and hashes should be selected after compatibility testing and security review rather than copied from an unverified example.

Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The description largely matches the intended domain and high-level behavior: the script processes manuscript-related image inputs (folders, single images, optionally PDFs), detects duplicate/similar images, and includes tampering-analysis routines based on CV techniques. It does not show undeclared exfiltration, networking, or unrelated system access. However, there is a material description/behavior mismatch because the declared purpose says it detects both duplication and tampering, while the actual code as written is unlikely to successfully perform tampering detection. In init, 'self.detect_tampering' is assigned a boolean flag, which overrides the class method 'detect_tampering'. Later, scan() checks 'if self.detect_tampering:' and then calls 'self.detect_tampering(images)', which would attempt to call a boolean and fail. Thus, a core advertised capability is broken in implementation. Duplicate detection behavior does align with the description.

Content

No source excerpt is available for this finding.

Possible Typosquatting: 'pil' resembles popular package 'pip'

High
Category
Supply Chain
Confidence
99% confidence
Finding

The requirement pil is highly suspicious because the legitimate modern imaging library is usually Pillow, while PIL itself is deprecated and package-name confusion is a classic typosquatting vector. If an attacker controls or publishes a confusingly named package, installation could execute arbitrary code during build or import, creating a direct supply-chain compromise.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill describes local script execution with file output behavior, but it does not declare any explicit tool scope such as permissions or allowed-tools. That makes its filesystem write capability implicit rather than constrained, increasing the chance that an agent or runner will execute it with broader write access than intended and making security review and enforcement harder.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This Python file contains natural-language descriptions in Chinese for the skill purpose, while the rest of the interface is mixed-language and there is no indication that users can choose their preferred language. The policy explicitly flags language or locale constraints when a skill forces a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The implementation claims to extract images from PDFs, but actually rasterizes full pages and analyzes page screenshots. This can materially mislead users about what was analyzed, causing false confidence in duplication or tampering results and potentially missing manipulated figures embedded within complex page layouts.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

For PDF inputs, the skill analyzes rendered pages instead of isolated manuscript figures, which does not match the advertised security-relevant behavior. In a scientific integrity workflow, this can lead to false negatives, false positives, and unsafe reliance on results when screening for duplicated or manipulated figures.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency list leaves cv2 unpinned, so builds may resolve to different versions over time, including vulnerable or breaking releases. In a security-sensitive image-processing skill, this weakens supply-chain integrity and makes it difficult to verify which package version is actually installed.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
cv2
dataclasses
imagehash
matplotlib

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
91% confidence
Finding

The dataclasses dependency is unpinned, which makes installs non-reproducible and can introduce unexpected package changes. This is lower risk than code execution issues, but it still creates avoidable supply-chain uncertainty.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
cv2
dataclasses
imagehash
matplotlib
numpy

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

An unpinned imagehash dependency allows arbitrary future releases to be installed, which can pull in vulnerable or incompatible versions without notice. For a manuscript-image analysis skill, deterministic and auditable dependency resolution is important because image-processing libraries often handle untrusted files.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
cv2
dataclasses
imagehash
matplotlib
numpy
pdf2image

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

matplotlib is unpinned, so the runtime may receive different versions across installs, reducing reproducibility and potentially introducing known vulnerable releases. While impact is limited here, it still expands supply-chain risk in a package that may process external content and render outputs.

Content

Scanner excerpt · requirements.txt (reported line 4)May include surrounding context.

text
cv2
dataclasses
imagehash
matplotlib
numpy
pdf2image
pil

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

numpy is unpinned even though it has a history of published advisories, so the environment could resolve to a vulnerable release and there is no way to verify safety from this manifest alone. Because this skill performs image and array processing, numpy is likely central to execution, increasing the importance of version control.

Content

Scanner excerpt · requirements.txt (reported line 5)May include surrounding context.

text
dataclasses
imagehash
matplotlib
numpy
pdf2image
pil

Unverifiable Dependency: numpy has 16 known advisory(ies) (CVE-2014-1859 (Numpy arbitrary file write via symlink attack); CVE-2021-41495 (NumPy NULL Pointer Dereference); CVE-2021-33430 (NumPy Buffer Overflow (Disputed)) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The manifest does not pin numpy, so it is impossible to determine whether the installed version is affected by known advisories. This is a real supply-chain exposure because a vulnerable version could be selected silently during installation.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

pdf2image is unpinned, which introduces non-deterministic installs and possible exposure to vulnerable upstream releases. This matters more in this skill because PDF/image conversion often processes user-supplied documents, a common attack surface.

Content

Scanner excerpt · requirements.txt (reported line 6)May include surrounding context.

text
imagehash
matplotlib
numpy
pdf2image
pil

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
99% confidence
Finding

The dependency entry pil is unpinned and also suspicious because PIL is obsolete and the common maintained package is Pillow. An ambiguous, unpinned package name increases the chance of installing an unintended or malicious package from the registry.

Content

Scanner excerpt · requirements.txt (reported line 7)May include surrounding context.

text
matplotlib
numpy
pdf2image
pil

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The code writes temporary page images and ELA recompression files to disk without clearly warning users, which can leave behind sensitive manuscript content on the filesystem. In research or pre-publication contexts, these artifacts may expose confidential data to other local users, backups, or later forensic recovery.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The report persists scanned file paths and findings to disk without explicit warning, which may leak sensitive manuscript names, locations, and integrity findings. In academic or regulated environments, such metadata persistence can create confidentiality and privacy issues if reports are shared or stored insecurely.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.