Back to skill

Security audit

Image Utils

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent image-processing helper, but users should treat its URL loading and optional Bria API examples as network-capable behavior.

Install is reasonable for local image processing. Before using URL loading, restrict it to trusted public image sources and avoid passing attacker-controlled, localhost, private-network, or cloud-metadata URLs. Review the separate bria-ai skill before installing it, and pin or approve the version where your environment supports that.

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

T09 · Insecure Skill Coding Practices

Warning
Location
references/code-examples/image_utils.py:82
Finding

Unrestricted URL Fetching Enables Server-Side Request Forgery

Content
View full analysis

Vulnerability Details

File Location: references/code-examples/image_utils.py, lines 82-107
Vulnerability Type: Server-Side Request Forgery through unrestricted image URL loading
Risk Level: Medium

Vulnerable Code

python
            # URL
            if source.startswith(("http://", "https://")):
                return ImageUtils.load_from_url(source)

            # File path
            return Image.open(source)

        raise ValueError(f"Unsupported source type: {type(source)}")

    @staticmethod
    def load_from_url(url: str, timeout: int = 30) -> Image.Image:
        """
        Download and load image from URL.

        Args:
            url: Image URL
            timeout: Request timeout in seconds

        Returns:
            PIL Image object
        """
        response = requests.get(
            url, timeout=timeout, headers={"User-Agent": "BriaSkills/1.3.4"}
        )
        response.raise_for_status()
        return Image.open(io.BytesIO(response.content))

Technical Analysis

The load() method treats any string beginning with http:// or https:// as a remotely retrievable image. The value is passed to requests.get() without validating the destination hostname or resolved IP address.

The implementation does not reject loopback, private, link-local, multicast, or reserved network ranges. It also does not constrain redirects, so a permitted-looking URL could redirect to an internal destination. Although remote image loading is part of the declared functionality, access to arbitrary internal network locations is not required to download public images and therefore exceeds minimum necessary network privileges.

The response is subsequently passed to Pillow and must normally represent a supported image for the method to return successfully. This limits direct response disclosure but does not prevent the outbound request itself. Timing, status-depend ...[truncated 1346 chars]

Remediation
View remediation

Remediation Suggestions

  • Permit HTTPS only unless plaintext HTTP is explicitly required.
  • Parse URLs with a standards-compliant parser and allow only expected schemes.
  • Resolve the hostname before connecting and reject loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 addresses.
  • Disable automatic redirects or validate the hostname and resolved address again for every redirect.
  • Where practical, use an explicit allowlist of trusted image hosts.
  • Route outbound downloads through a restricted proxy with network-level egress controls.
  • Apply a maximum response size and stream the body rather than loading an unlimited response into memory.
  • Validate the response content type and verify image data before further processing.
  • Use separate connection and read timeouts and impose a maximum redirect count.

T08 · Insecure Dependencies

Note
Location
SKILL.md:34
Finding

Unpinned External Skill Installation Creates Supply-Chain Risk

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 34-38
Vulnerability Type: Mutable and unverified third-party Skill installation
Risk Level: Low

Vulnerable Code

markdown
If `bria-ai` is not available, install it with:
```bash
npx skills add bria-ai/bria-skill
text

### Technical Analysis

The documentation instructs users or Agents to install an external Skill by a mutable repository-style identifier. It does not pin an immutable version or commit, provide a checksum, or require review of the retrieved content.

Consequently, the installed content may differ from the content present when this Skill was audited. A compromise of the upstream account, repository, registry resolution process, or installer could introduce malicious instructions or executable components. The audited project itself does not fetch or execute a remote payload automatically; exploitation requires a user or Agent to follow the installation instruction.

### Attack Path

1. An attacker compromises or maliciously changes the external `bria-ai/bria-skill` source or its resolution path.
2. A user or Agent follows the documented `npx skills add bria-ai/bria-skill` instruction.
3. The installer retrieves the current mutable external content rather than a reviewed immutable revision.
4. The newly installed Skill is later loaded or invoked with the Agent's available permissions.
5. Malicious instructions or code in that external Skill operate within those permissions.

### Impact Assessment

The potential impact depends entirely on the permissions granted to the external Skill and its installer. In a highly privileged Agent environment, a compromised dependency could access files, credentials, tools, or network resources available to the Agent.

No malicious behavior was identified in the audited project, and the external Skill's contents were not part of the provided artifact. This finding therefore represents a supply-c
...[truncated 89 chars]
Remediation
View remediation

Remediation Suggestions

  • Pin the external Skill to an immutable, reviewed release or commit.
  • Publish and verify a cryptographic checksum or signature for the expected artifact.
  • Require explicit user approval before installing an additional Skill.
  • Review the pinned dependency's instructions and executable files before granting it access to Agent tools.
  • Use a trusted registry or repository and enable provenance verification where supported.
  • Run third-party Skills with restricted filesystem, network, credential, and tool permissions.
  • Establish a controlled update process so newer versions are reviewed before the pin is changed.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (11)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill documents network-capable behavior such as loading images from URLs and calling an external Bria API, but it does not declare any tool scope or permissions boundary. This creates a trust gap where users may assume the skill is local-only while it can trigger outbound requests, increasing the risk of unintended data egress or policy bypass in an agent environment.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
81% confidence
Finding

The documentation instructs users to install another skill via npx skills add bria-ai/bria-skill without pinning a specific version or immutable reference. This introduces supply-chain risk because future changes to that external package could silently alter behavior or introduce malicious code.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
74% confidence
Finding

This duplicate finding identifies the same outbound POST example, which constitutes external data transmission to a remote API. In the context of a skill marketed primarily for image utilities, the networked integration becomes more security-relevant because users may not expect prompt content or API usage to leave the environment.

Content

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

md
from image_utils import ImageUtils

# Generate with Bria AI (see bria-ai skill for full API reference)
response = requests.post(
    "https://engine.prod.bria-api.com/v2/image/generate",
    headers={"api_token": BRIA_API_KEY, "Content-Type": "application/json"},
    json={"prompt": "product photo of headphones", "aspect_ratio": "1:1", "sync": True}

External Transmission

Medium
Category
Data Exfiltration
Confidence
74% confidence
Finding

This duplicate finding identifies the same outbound POST example, which constitutes external data transmission to a remote API. In the context of a skill marketed primarily for image utilities, the networked integration becomes more security-relevant because users may not expect prompt content or API usage to leave the environment.

Content

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

md
from image_utils import ImageUtils

# Generate with Bria AI (see bria-ai skill for full API reference)
response = requests.post(
    "https://engine.prod.bria-api.com/v2/image/generate",
    headers={"api_token": BRIA_API_KEY, "Content-Type": "application/json"},
    json={"prompt": "product photo of headphones", "aspect_ratio": "1:1", "sync": True}

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest frames this skill as classic local image manipulation and post-processing, but the module documentation and implementation explicitly support loading images from remote URLs. That introduces external network access behavior beyond deterministic pixel-level processing itself, which is not stated in the manifest description.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The import and later use of requests adds outbound network capability to a skill whose stated purpose is image resizing, cropping, compositing, format conversion, and related Pillow operations. While convenient, network access is not an obvious requirement for deterministic image post-processing and is not declared in the manifest text.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

load_from_url fetches arbitrary user-supplied URLs, which can enable SSRF-style access to internal services or unintended outbound requests when used in a privileged environment. It also accepts unvalidated remote content directly into Pillow, increasing exposure to denial-of-service or parser-triggered issues from malicious files.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill is presented as deterministic pixel-level local image processing, but the quick reference prominently includes loading from arbitrary URLs. This mismatch can mislead users about the trust boundary and may cause them to expose internal services or fetch attacker-controlled content through the host environment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The examples perform outbound requests and write files to disk without warning users that prompts, images, and local filesystem contents may be transmitted or overwritten. In agentic contexts, lack of disclosure can lead to unsafe automation decisions and accidental data handling beyond user expectations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This code file performs an outbound HTTP request to fetch image data from a provided URL. Although the function docstring says it downloads an image, there is no confirmation prompt or explicit warning that calling this method will contact a remote host and transmit request metadata such as the URL and headers.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The save method creates parent directories if needed and writes output files to disk, which changes the local filesystem state. While the function name implies saving, the code lacks any explicit warning or disclosure about directory creation and overwriting/creating files at the target path.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.