Back to skill

Security audit

摄影照片评分Aesthetic Scorer

Security checks for vulnerabilities and agentic risk

Overview

The skill appears designed to score photos locally, but its setup asks users to trust unpinned third-party ML code despite strong offline/privacy claims.

Install only in an isolated virtual environment or container, avoid running setup as administrator/root, pin or verify the external repository commits and package versions before installing, and treat the offline privacy promise as applying to runtime image scoring rather than initial setup downloads.

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 (2)

T08 · Insecure Dependencies

Warning
Location
README.md:101
Finding
Mutable Third-Party Repositories Are Installed Without Commit Pinning<![CDATA[ ## Vulnerability Details **File Location**: `README.md:101-103` and `README.md:112-114` **Vulnerability Type**: Supply-chain exposure through mutable third-party repositories **Risk Level**: Medium ### Vulnerable Code ```bash # README.md:101-103 git clone https://github.com/christophschuhmann/improved-aesthetic-predictor cd improved-aesthetic-predictor pip install -r requirements.txt ``` ```bash # README.md:112-114 git clone https://github.com/titu1994/neural-image-assessment cd neural-image-assessment pip install -r requirements.txt ``` ### Technical Analysis The installation instructions clone the default branches of two external GitHub repositories without pinning them to reviewed, immutable commit hashes or release tags. The instructions then immediately install each repository's dependency list. Because the effective repository contents and transitive requirements can change after this Skill has been reviewed, the audited package does not fully define the code that users are instructed to trust. If an upstream repository, maintainer account, default branch, or transitive dependency is compromised, later installations can receive content that was not present during this audit. The commands do not directly execute a repository script, but `pip install -r requirements.txt` can install packages that execute build backends or other installation-time behavior. The external requirement files were not included in the audited project, so their complete dependency graphs and integrity controls could not be verified. ### Attack Path 1. An attacker compromises one of the referenced upstream repositories, a maintainer account, or a dependency named in an upstream `requirements.txt`. 2. The attacker modifies the default branch or dependency declarations to introduce a malicious package or build process. 3. A user follows the documented installation procedure and clones the mutable default branch. 4. The user runs `pip install -r requirements.txt`. 5 ...[truncated 828 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin each external repository to a reviewed commit hash: ```bash git clone https://github.com/christophschuhmann/improved-aesthetic-predictor cd improved-aesthetic-predictor git checkout --detach <reviewed-commit-sha> ``` 2. Publish the expected commit hashes in the documentation and verify them before installation. 3. Prefer signed, versioned releases where maintainers provide verifiable signatures or attestations. 4. Audit and lock every transitive dependency from the external repositories. 5. Use an isolated virtual environment or container with minimum filesystem and network privileges. 6. Generate a hash-locked dependency file and install it with: ```bash pip install --require-hashes -r requirements.lock ``` 7. Add automated dependency and repository-integrity monitoring so changes to pinned sources require a new security review. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:5
Finding
Python Dependencies Use Open-Ended Version Constraints Without Integrity Hashes<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:5-29` **Vulnerability Type**: Unlocked and unverified package dependencies **Risk Level**: Medium ### Vulnerable Code ```text # PyTorch and torchvision (for CLIP + MLP model) torch>=2.0.0 torchvision>=0.15.0 # Transformers (for CLIP model loading) transformers>=4.30.0 # TensorFlow/Keras (for NIMA MobileNet model) # Use tf_keras for better compatibility with TensorFlow 2.x tensorflow>=2.12.0 tf_keras>=2.12.0 # Image processing Pillow>=10.0.0 # HTTP requests requests>=2.25.0 # Numerical computing numpy>=1.23.0 # Optional: for visualization matplotlib>=3.7.0 # Optional: for progress bars tqdm>=4.65.0 ``` ### Technical Analysis All declared packages use minimum-version constraints rather than exact versions. There are no package hashes, lockfile entries, index restrictions, or provenance attestations. Consequently, the same installation command can resolve to different package versions and transitive dependency graphs over time. If a future release is compromised, malicious, or incompatible, it can be selected automatically while still satisfying the `>=` constraint. Python packages may execute code through their build backends during installation, making dependency integrity a direct code-execution concern rather than only a reproducibility issue. The audited scripts do not use `requests`, `matplotlib`, or `tqdm`. Keeping these packages in the installation set unnecessarily expands the dependency graph and supply-chain attack surface. ### Attack Path 1. An attacker compromises a declared package, one of its transitive dependencies, or an associated publishing account. 2. A malicious release is published with a version satisfying the open-ended minimum constraint. 3. A user installs the project with `pip install -r requirements.txt`. 4. The package resolver selects the malicious release because no exact version or trusted hash is required. 5. Malicious installation-time or runt ...[truncated 694 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace minimum-version constraints with exact, tested versions in a lockfile. 2. Record cryptographic hashes for every direct and transitive artifact. 3. Install with hash enforcement: ```bash pip install --require-hashes -r requirements.lock ``` 4. Restrict package installation to an explicitly configured trusted index. 5. Remove unused dependencies, particularly `requests`, `matplotlib`, and `tqdm`, unless the project introduces code that requires them. 6. Separate required and optional dependencies into distinct locked files or extras. 7. Regularly scan dependencies for known vulnerabilities and require review before lockfile updates. 8. Perform installations in an isolated, non-privileged environment rather than as an administrator or root user. ]]>
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (26)

Intent-Code Divergence

Medium
Confidence
90% confidence
Finding
The privacy section states '100% Local Processing', 'No Data Transmission', and 'Works completely offline', which communicates a strong no-network expectation for the skill. Later documentation explicitly requires network access to Git clone repositories and download model weights from GitHub, so the documentation contradicts itself about whether network access is needed.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The basic usage triggers are highly generic requests such as 'Evaluate this photo' and 'Analyze the beauty of this picture', which are common user intents in many contexts. In a multi-skill assistant, ambiguous triggers increase the risk of accidental invocation, unintended image processing, and prompt routing conflicts with other tools.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The comparison/evaluation example phrases are broad natural-language requests that overlap with ordinary conversation about photos. In an agent environment, this can cause unintentional skill activation and routing of user images or prompts into this skill when the user did not explicitly intend to invoke it.

Lp3

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding
The skill describes access to environment-controlled model paths and a local Python runtime, but it does not declare an explicit tool/permission scope. That mismatch can cause the host agent to invoke local execution or read environment configuration without transparent user-facing authorization boundaries, increasing the risk of unintended file or environment access.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The file instructs the skill to always display the "从夯到拉" rating labels such as "夯", "NPC", and "拉完了" in outputs, and line L339 reinforces that this rating level must always be shown. This is a natural-language policy concern because it forces a particular locale/register-specific style on all users rather than offering a choice or opt-in.

Vague Triggers

Medium
Confidence
90% confidence
Finding
This JSON manifest sets a hard default language of "zh-CN" for the skill, but the file does not indicate that the skill is limited to Chinese-speaking users or that users can choose another locale. In manifest/config files, forcing a locale without clear constraints can create unintended behavior and overlaps with both vague configuration scope and organizational language policy concerns.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The configuration explicitly sets the skill language to "zh-CN", and no nearby text indicates that users may choose another language or that the skill is region-specific. This is a natural-language policy concern because it imposes a locale choice by default rather than offering user choice or documenting a justified constraint.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This Python file hard-codes Chinese user-facing labels and console/report text, including the score taxonomy and progress messages. Because the skill does not offer a language/locale option or document a justified region-specific restriction, it violates the policy against forcing a specific language without user opt-in.

Natural-Language Policy Violations

Low
Confidence
78% confidence
Finding
The README states "Bilingual Support" with Chinese and English, but it does not clearly say the user can choose the output language or opt out of bilingual behavior. Under the policy, language behavior should be user-selectable unless the locale constraint is explicitly justified.

Unpinned Dependencies

Low
Category
Supply Chain
Content
# Install with: pip install -r requirements.txt

# PyTorch and torchvision (for CLIP + MLP model)
torch>=2.0.0
torchvision>=0.15.0

# Transformers (for CLIP model loading)
Confidence
97% confidence
Finding
The dependency is specified with a lower-bound only, which allows future installs to resolve to different versions over time. This weakens reproducibility and can unintentionally introduce vulnerable or incompatible releases through normal dependency resolution or supply-chain compromise.

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
94% confidence
Finding
torch has known advisories, and because the manifest does not pin a version, there is no way to verify whether deployments will receive a patched or affected release. In an ML skill this matters because model-loading features can intersect with deserialization and native-code attack surfaces.

Unpinned Dependencies

Low
Category
Supply Chain
Content
# PyTorch and torchvision (for CLIP + MLP model)
torch>=2.0.0
torchvision>=0.15.0

# Transformers (for CLIP model loading)
transformers>=4.30.0
Confidence
97% confidence
Finding
The dependency is unpinned and may resolve to different torchvision versions across environments or over time. That increases supply-chain risk and makes it impossible to guarantee that only vetted versions are installed.

Unpinned Dependencies

Low
Category
Supply Chain
Content
torchvision>=0.15.0

# Transformers (for CLIP model loading)
transformers>=4.30.0

# TensorFlow/Keras (for NIMA MobileNet model)
# Use tf_keras for better compatibility with TensorFlow 2.x
Confidence
97% confidence
Finding
Using transformers>=4.30.0 permits installation of any newer release, including versions that may later contain security regressions or breaking behavior. In ML tooling that often downloads models and processes external data, version drift increases security uncertainty.

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, but the open-ended version specifier prevents determining whether installed versions are vulnerable. Given that this library may fetch and parse model assets, leaving the version unresolved creates unnecessary security uncertainty.

Unpinned Dependencies

Low
Category
Supply Chain
Content
# TensorFlow/Keras (for NIMA MobileNet model)
# Use tf_keras for better compatibility with TensorFlow 2.x
tensorflow>=2.12.0
tf_keras>=2.12.0

# Image processing
Confidence
97% confidence
Finding
An unpinned tensorflow dependency allows non-deterministic installation results and makes security posture unverifiable. Because TensorFlow is a large native-code package with a history of parser and memory-safety issues, uncontrolled upgrades increase risk.

Unverifiable Dependency: tensorflow has 16 known advisory(ies) (CVE-2022-21726 (Out of bounds read in Tensorflow); CVE-2022-35968 (TensorFlow vulnerable to `CHECK` fail in `AvgPoolGrad`); CVE-2022-23591 (Stack overflow in TensorFlow) +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
tensorflow has published advisories, and without exact version pinning the deployed package may still be affected. Since it includes complex native and parser-heavy components, unverifiable version selection is a meaningful dependency-management weakness.

Unpinned Dependencies

Low
Category
Supply Chain
Content
# TensorFlow/Keras (for NIMA MobileNet model)
# Use tf_keras for better compatibility with TensorFlow 2.x
tensorflow>=2.12.0
tf_keras>=2.12.0

# Image processing
Pillow>=10.0.0
Confidence
95% confidence
Finding
The tf_keras package is not pinned, so installations may pull different versions with differing behavior or exposure to known issues. This creates avoidable supply-chain and reproducibility risk.

Unpinned Dependencies

Low
Category
Supply Chain
Content
tf_keras>=2.12.0

# Image processing
Pillow>=10.0.0

# HTTP requests
requests>=2.25.0
Confidence
97% confidence
Finding
Pillow handles untrusted image data, so allowing arbitrary newer versions without pinning increases the chance that an affected release is installed. For an image-scoring skill, this context makes version control more important because image parsing is directly in scope.

Unverifiable Dependency: Pillow has 16 known advisory(ies) (CVE-2016-2533 (Pillow buffer overflow in ImagingPcdDecode); CVE-2023-50447 (Arbitrary Code Execution in Pillow); CVE-2021-27922 (Pillow Uncontrolled Resource Consumption) +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
96% confidence
Finding
Pillow has known security issues and this skill is explicitly designed to process user-supplied photos, making image-decoder vulnerabilities more relevant than in many other contexts. Because the dependency is not pinned, a deployment could resolve to an affected version without any guarantee of safety.

Unpinned Dependencies

Low
Category
Supply Chain
Content
Pillow>=10.0.0

# HTTP requests
requests>=2.25.0

# Numerical computing
numpy>=1.23.0
Confidence
96% confidence
Finding
requests>=2.25.0 does not guarantee a specific vetted version and can lead to inconsistent environments or installation of versions later found vulnerable. This is a standard dependency hygiene issue rather than evidence of active maliciousness.

Unverifiable Dependency: requests has 16 known advisory(ies) (GHSA-652x-xj99-gmcc; GHSA-9hjg-9r4m-mvj7; GHSA-9wx4-h78v-vm56 +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
91% confidence
Finding
requests has known advisories, but the unpinned requirement makes it impossible to verify whether the runtime version is fixed. This is mainly a dependency hygiene and supply-chain assurance problem in the provided file.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.25.0

# Numerical computing
numpy>=1.23.0

# Optional: for visualization
matplotlib>=3.7.0
Confidence
95% confidence
Finding
An unpinned numpy dependency allows uncontrolled version selection and undermines reproducibility. While not always directly exploitable, it increases operational and supply-chain risk and complicates vulnerability management.

Unverifiable Dependency: numpy has 16 known advisory(ies) (GHSA-2fc2-6r4j-p65h; GHSA-5545-2q6w-2gh6; GHSA-6p56-wp2h-9hxr +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
90% confidence
Finding
numpy has advisories and the manifest does not fix the installed version, so affected builds cannot be ruled out. The risk is lower than directly exposed parsing libraries, but the lack of verifiability remains a real weakness.

Unpinned Dependencies

Low
Category
Supply Chain
Content
numpy>=1.23.0

# Optional: for visualization
matplotlib>=3.7.0

# Optional: for progress bars
tqdm>=4.65.0
Confidence
90% confidence
Finding
matplotlib is optional, but leaving it unpinned still permits unexpected version drift and unverifiable security status. The optional nature slightly reduces severity, but not the underlying hygiene issue.

Unpinned Dependencies

Low
Category
Supply Chain
Content
matplotlib>=3.7.0

# Optional: for progress bars
tqdm>=4.65.0
Confidence
90% confidence
Finding
The tqdm package is unpinned, allowing unreviewed newer versions to be installed. Although a progress-bar library is less sensitive than image or model-parsing components, it still contributes to avoidable supply-chain risk.

Static analysis

No suspicious patterns detected.