Back to skill

Security audit

本地图片语义搜索

Security checks for vulnerabilities and agentic risk

Overview

This skill is a real local image search tool, but it defaults to broad local image indexing and uses under-controlled model and dependency loading that users should review carefully.

Install only if you are comfortable with it scanning broad local image locations, storing image paths/features in image_db, downloading a model through hf-mirror.com, and writing query results to your Desktop. Prefer editing SCAN_ROOTS to specific folders, using an isolated Python environment, pinning dependencies, and replacing the pickle index format before relying on it.

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)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/search.py:31
Finding
Unsafe Deserialization of Local Pickle Index Files<![CDATA[ ## Vulnerability Details **File Location**: `scripts/search.py:31-32`; `scripts/update.py:138-139` **Vulnerability Type**: Unsafe Python pickle deserialization **Risk Level**: High ### Vulnerable Code `scripts/search.py:31-32`: ```python with open(IMAGE_LIST_FILE, 'rb') as f: images = pickle.load(f) ``` `scripts/update.py:138-139`: ```python with open(IMAGE_LIST_FILE, 'rb') as f: existing_paths = pickle.load(f) ``` ### Technical Analysis The application loads `image_db/image_list.pkl` with Python's unrestricted `pickle.load()` function. Pickle is an executable serialization format: specially constructed objects can define reduction operations that invoke attacker-selected Python callables during deserialization. No signature, digest, ownership check, permission check, schema validation, or restricted unpickler is applied before the file is loaded. Consequently, the fact that the file is stored locally does not make deserialization safe. Any actor or process capable of modifying the project database directory can turn the index file into a code-execution vector. Both the search and incremental-update workflows reach the unsafe operation. The payload executes while the file is being loaded, before the path list is used for its intended purpose. ### Attack Path 1. An attacker obtains write access to the project directory or `image_db/image_list.pkl`. This could occur through another local account with applicable permissions, a compromised process, an unsafe archive extraction, or replacement of a shared project directory. 2. The attacker generates a malicious pickle whose deserialization reduction invokes an attacker-selected callable, such as a process-launch or file-operation function. 3. The attacker replaces the legitimate `image_list.pkl` with the malicious file. 4. The victim runs either `python scripts/search.py <query>` or `python scripts/update.py`. 5. `pickle.load()` processes the attacker-controlled object. 6. The embedded ...[truncated 715 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace pickle storage with a non-executable serialization format such as JSON: ```python import json with open(IMAGE_LIST_FILE, "r", encoding="utf-8") as f: images = json.load(f) if not isinstance(images, list) or not all(isinstance(path, str) for path in images): raise ValueError("Invalid image-list format") ``` 2. Update the writer to serialize the list using `json.dump()` and change the configured filename to `image_list.json`. 3. Validate the decoded structure, maximum entry count, individual path length, and expected value types before using the data. 4. Store index data in a user-private directory and apply permissions that prevent modification by other accounts. 5. If integrity against unauthorized modification is required, authenticate the index and path-list files with a signature or keyed MAC stored separately. 6. Do not attempt to make arbitrary pickle data safe through superficial type checks after loading; malicious behavior occurs during deserialization. 7. If a legacy migration is required, only convert pickle files generated in a trusted environment after checking file ownership and permissions, then delete the pickle file. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/config.py:5
Finding
Model Artifacts Are Retrieved Through a Forced Third-Party Mirror Without Revision Pinning<![CDATA[ ## Vulnerability Details **File Location**: `scripts/config.py:5`; `scripts/scan.py:73-80`; `scripts/search.py:44-51`; `scripts/update.py:74-81` **Vulnerability Type**: Unverified third-party model supply chain **Risk Level**: Medium ### Vulnerable Code `scripts/config.py:5`: ```python os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com' ``` `scripts/scan.py:73-80`: ```python # 尝试本地加载,如果失败则联网下载 try: model = ChineseCLIPModel.from_pretrained(MODEL_NAME, local_files_only=True) processor = ChineseCLIPProcessor.from_pretrained(MODEL_NAME, local_files_only=True) except: print("本地模型不存在,正在下载(首次运行需要网络连接)...") model = ChineseCLIPModel.from_pretrained(MODEL_NAME) processor = ChineseCLIPProcessor.from_pretrained(MODEL_NAME) ``` `scripts/search.py:44-51`: ```python # 尝试本地加载,如果失败则联网下载 try: model = ChineseCLIPModel.from_pretrained(MODEL_NAME, local_files_only=True) processor = ChineseCLIPProcessor.from_pretrained(MODEL_NAME, local_files_only=True) except: print("本地模型不存在,正在下载...") model = ChineseCLIPModel.from_pretrained(MODEL_NAME) processor = ChineseCLIPProcessor.from_pretrained(MODEL_NAME) ``` `scripts/update.py:74-81`: ```python # 尝试本地加载,如果失败则联网下载 try: model = ChineseCLIPModel.from_pretrained(MODEL_NAME, local_files_only=True) processor = ChineseCLIPProcessor.from_pretrained(MODEL_NAME, local_files_only=True) except: print("本地模型不存在,正在下载(首次运行需要网络连接)...") model = ChineseCLIPModel.from_pretrained(MODEL_NAME) processor = ChineseCLIPProcessor.from_pretrained(MODEL_NAME) ``` ### Technical Analysis The Skill unconditionally overrides `HF_ENDPOINT` with `https://hf-mirror.com`, directing model retrieval through a third-party service rather than the official Hugging Face endpoint. When no cached model is available, `from_pretrained()` downloads the model and processor through that endpoint. The configured model is identified only by the mutable repository name `OFA-Sys/chinese-clip-vit-base-patch16`. ...[truncated 2216 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not unconditionally override `HF_ENDPOINT`. Use the official endpoint by default and make alternate mirrors an explicit, documented opt-in setting. 2. Pin the model to a reviewed immutable commit: ```python MODEL_REVISION = "<reviewed-commit-sha>" model = ChineseCLIPModel.from_pretrained( MODEL_NAME, revision=MODEL_REVISION, use_safetensors=True, ) processor = ChineseCLIPProcessor.from_pretrained( MODEL_NAME, revision=MODEL_REVISION, ) ``` 3. Prefer `safetensors` model weights and reject executable or pickle-based model formats where supported. 4. Record and verify cryptographic hashes of all expected model, tokenizer, processor, and configuration files. 5. Pre-download and validate artifacts in a controlled installation step, then use `local_files_only=True` during normal operation. 6. Catch only expected cache-miss exceptions. Do not use a bare `except:`, because unrelated corruption or security failures should not silently enable network retrieval. 7. Document the model source, immutable revision, expected files, and verification procedure for administrators. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:4
Finding
Python Dependencies Are Unpinned and Installed Without Integrity Hashes<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:4-15` **Vulnerability Type**: Uncontrolled dependency resolution and missing package integrity verification **Risk Level**: Medium ### Vulnerable Code `requirements.txt:4-15`: ```text # 深度学习模型 torch>=2.0.0 transformers>=4.30.0 # 向量数据库 faiss-cpu>=1.7.0 # 或 conda install faiss-cpu(如果pip安装失败) # 图片处理 Pillow>=9.0.0 # 进度条 tqdm>=4.60.0 ``` The documented installation command in `SKILL.md:27-28` is: ```bash pip install -r requirements.txt ``` ### Technical Analysis Every runtime dependency uses an open-ended lower-bound constraint. The resolver can therefore select future releases that were not reviewed or tested with the Skill. No lock file, exact version, package hash, or trusted-index constraint is supplied. Python packages can execute code during installation and later during import. If a permitted future release is compromised, malicious, or incompatible, following the documented installation command can introduce that release into the environment. No typosquatted package name or known malicious package was identified in the reviewed dependency list. The issue is the absence of reproducible resolution and artifact integrity controls, rather than evidence that the currently named projects are malicious. ### Attack Path 1. A user follows the documented `pip install -r requirements.txt` instruction. 2. The package resolver queries the configured Python package index and selects versions satisfying the broad `>=` constraints. 3. A compromised future release, substituted distribution, or unexpectedly unsafe version satisfies those constraints. 4. Because no expected hashes are configured, installation proceeds without detecting artifact substitution. 5. Package-controlled code runs during installation or when the application imports the dependency. 6. The code runs with the privileges of the user performing installation or executing the Skill. ### Impact Assessment A malicious depe ...[truncated 564 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin all direct and transitive dependencies to versions that have been reviewed and tested. 2. Generate a reproducible lock file using a tool such as `pip-tools`, Poetry, or uv. 3. Require package hashes during installation. For pip-based workflows, generate a hashed requirements file and install it with: ```bash python -m pip install --require-hashes -r requirements.lock ``` 4. Explicitly configure approved package indexes and use HTTPS. Avoid adding untrusted extra indexes that could enable dependency confusion. 5. Install dependencies inside a dedicated virtual environment as a non-administrator user. 6. Add automated dependency vulnerability and provenance scanning to the update process. 7. Review dependency updates individually and regenerate hashes only after validating release provenance, compatibility, and security advisories. ]]>
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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (32)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared purpose frames the skill as a local image search tool, but the documentation also reveals undeclared network model downloads and writing search results to the user's desktop. This mismatch is dangerous because users may consent to local search without realizing the skill will contact external services or create visible artifacts containing sensitive file paths and query-related data.

Natural-Language Policy Violations

Medium
Confidence
80% confidence
Finding
The README is written entirely in Chinese and presents the tool as centered on Chinese support and Chinese-language examples, without offering an alternate language or clarifying that the locale is intentionally limited. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The README instructs users to scan all detected drives by default and states that search results are automatically saved to the desktop, but it does not clearly warn that the tool will traverse broad portions of the local filesystem and create output files. In a local desktop skill, this is a meaningful transparency and consent issue because users may not expect extensive file enumeration or desktop artifact creation, which can expose sensitive filenames, image metadata, or copied/exported results.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill performs sensitive capabilities—reading local files across multiple drives, writing output files, and using environment/network-related configuration—without explicitly declaring any tool scope or permissions boundary. This is dangerous because reviewers and users cannot easily understand or constrain what the skill may access, increasing the risk of overbroad file exposure or unintended data handling.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill scans entire drives and builds an index of local images, which can reveal sensitive personal content and path metadata, yet the description lacks a prominent privacy warning or consent step. In this context, full-disk semantic indexing materially increases privacy risk because users may not expect broad analysis of personal photos, screenshots, documents-as-images, or other sensitive media.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The code silently overrides the Hugging Face network endpoint to a mirror URL, so users may believe the tool contacts the default upstream service when it actually sends requests to a different external destination. In a local image-search skill, this is more concerning because users may expect fully local operation except for model setup, making undisclosed outbound traffic and altered supply sources more likely to violate trust and security expectations.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The configuration unconditionally forces model downloads and metadata requests through a third-party HuggingFace mirror. This changes the trust boundary for model supply and network traffic without user consent, creating risk of tampered model artifacts, unexpected data disclosure about model usage, or failures if the mirror is untrusted or compromised.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The module docstring and all user-facing console messages are written only in Chinese, indicating the skill is designed around a fixed language experience. Under the policy, locale constraints should either offer user opt-in/choice or be clearly documented as justified for a region-specific tool, which is not present here.

Description-Behavior Mismatch

Medium
Confidence
89% confidence
Finding
If no roots are configured, the script enumerates all available drives and recursively scans them for images. For a local photo search tool, this is broader than necessary and may collect sensitive images from unrelated directories, removable media, or enterprise/network-mounted locations, increasing privacy and data-minimization risk.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The script claims to be a local image search/indexing tool, but it silently falls back to downloading a model from the network when local files are missing. This expands the trust boundary to a remote model source and can leak metadata about usage or introduce supply-chain risk if the remote endpoint or model artifact is tampered with.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The script configures a Hugging Face mirror endpoint and falls back to downloading models from the network when local files are unavailable. That adds undeclared network access and a supply-chain risk surface to a tool presented as a local image-search utility, especially if users assume it operates fully offline.

Insecure deserialization: pickle.load()

Medium
Category
Dangerous Code Execution
Content
index = faiss.read_index(INDEX_FILE)
    
    with open(IMAGE_LIST_FILE, 'rb') as f:
        images = pickle.load(f)
    
    return index, images
Confidence
95% confidence
Finding
The script deserializes IMAGE_LIST_FILE with pickle.load(), which can execute arbitrary code if the file is replaced or tampered with. In a local desktop skill that reads files from disk, this is especially risky because a poisoned cache/index artifact could trigger code execution the next time a user runs search.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The script automatically writes search results to a file on the user's Desktop, which is a side effect not implied by a simple search operation. This can leak sensitive file paths or search terms into an easily visible location and creates persistent artifacts without explicit user consent.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
Automatically persisting search results to the Desktop without prior warning or confirmation violates least surprise and can expose sensitive search history and filesystem paths. In a local photo-search context, those paths may reveal personal directory names, projects, or private content categories.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The file’s natural-language description is entirely Chinese and identifies the skill as a Chinese-image-search update script, while the implementation specifically imports `ChineseCLIPModel` and `ChineseCLIPProcessor`. There is no visible user opt-in, language choice, or justification that the skill is intended only for a Chinese-specific region or compliance context.

Context-Inappropriate Capability

Medium
Confidence
88% confidence
Finding
When roots are not configured, the script enumerates all drive letters and recursively scans them for images. That is broader filesystem access than necessary for the stated purpose and can expose sensitive files, increase privacy risk, and cause unexpected indexing of personal or corporate content.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The update script falls back to downloading a model from the network when it is not present locally, despite being presented as a local image-search tool. This expands the trust boundary to remote model delivery and mirror infrastructure, creating supply-chain and privacy risks if the download source is compromised or if network use is unexpected in a local-only workflow.

Insecure deserialization: pickle.load()

Medium
Category
Dangerous Code Execution
Content
index = faiss.read_index(INDEX_FILE)
    
    with open(IMAGE_LIST_FILE, 'rb') as f:
        existing_paths = pickle.load(f)
    
    return index, existing_paths
Confidence
97% confidence
Finding
The script deserializes IMAGE_LIST_FILE with pickle.load(), which can execute arbitrary code if that file is replaced or tampered with. Because this tool scans broad local storage and is likely run interactively by a user on their own machine, a malicious local file or poisoned database state could turn a routine index update into code execution.

Missing User Warnings

Low
Confidence
83% confidence
Finding
The README says the first run will automatically download a large model and later references use of the hf-mirror.com mirror, but it does not clearly disclose that the tool initiates network access to a third-party source. This creates a transparency and supply-chain trust concern, especially in environments where outbound network access is restricted or where users assume the skill is fully local.

Missing User Warnings

Low
Confidence
88% confidence
Finding
Saving search results to a desktop text file can expose sensitive image paths and search terms in a user-visible, easily discoverable location without an explicit warning. While lower severity than full-disk scanning, it still creates unnecessary disclosure risk on shared devices or systems with synced desktops.

Unpinned Dependencies

Low
Category
Supply Chain
Content
# 图片AI搜索工具 - 依赖列表

# 深度学习模型
torch>=2.0.0
transformers>=4.30.0

# 向量数据库
Confidence
95% confidence
Finding
The dependency specification uses a minimum version (torch>=2.0.0) rather than a pinned or tightly constrained version, which makes builds non-reproducible and can result in installation of unexpectedly vulnerable or breaking releases. In this skill context, torch is a high-risk package because ML frameworks often process complex model files and binary components, so supply-chain or vulnerable-version exposure is meaningful even though the file itself does not directly execute malicious code.

Unverifiable Dependency: torch has 16 known advisory(ies) (CVE-2025-2953 (PyTorch susceptible to local Denial of Service); CVE-2022-45907 (PyTorch vulnerable to arbitrary code execution); CVE-2025-32434 (PyTorch: `torch.load` with `weights_only=True` leads to remote code execution) +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
93% confidence
Finding
torch has multiple known advisories, and because the manifest does not pin a version there is no way to verify whether deployed environments will avoid affected releases. In this skill, PyTorch is central to model loading and inference, so an inadvertently vulnerable version could materially increase the chance of denial of service or code-execution issues if unsafe APIs or crafted artifacts are involved.

Unpinned Dependencies

Low
Category
Supply Chain
Content
# 深度学习模型
torch>=2.0.0
transformers>=4.30.0

# 向量数据库
faiss-cpu>=1.7.0
Confidence
95% confidence
Finding
transformers>=4.30.0 is unpinned, so installations may resolve to different versions over time, including versions with newly introduced vulnerabilities or unsafe dependency chains. This is more relevant here because the skill explicitly downloads a CLIP model on first run, increasing exposure to the model/package supply chain around the Hugging Face ecosystem.

Unverifiable Dependency: transformers has 16 known advisory(ies) (CVE-2023-2800 (transformers has Insecure Temporary File); CVE-2026-4372 (HuggingFace transformers vulnerable to remote code execution); CVE-2025-3933 (Transformers is vulnerable to ReDoS attack through its DonutProcessor class) +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
94% confidence
Finding
transformers has known advisories, and the lack of version pinning makes it impossible to determine whether installations are exposed to a vulnerable release. This skill's explicit model-download behavior and reliance on model/tokenizer processing make that uncertainty more dangerous than in a static utility package.

Unpinned Dependencies

Low
Category
Supply Chain
Content
transformers>=4.30.0

# 向量数据库
faiss-cpu>=1.7.0
# 或 conda install faiss-cpu(如果pip安装失败)

# 图片处理
Confidence
91% confidence
Finding
faiss-cpu>=1.7.0 is not pinned, so the resolved package may vary by install time and environment, reducing reproducibility and complicating assurance that only tested versions are deployed. Although this requirement alone is not an exploit, unpinned native-code packages can increase operational and supply-chain risk.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/scan.py:83

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/search.py:54

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/update.py:84