Back to skill

Security audit

Image generation, editing and remove background

Security checks for vulnerabilities and agentic risk

Overview

The skill is a legitimate Bria image-generation integration, but its examples can expose API keys and upload local or internal data if followed as written.

Install only if you are comfortable sending prompts and chosen image content to Bria. Do not paste API keys into chat or print them with echo; configure them through a private environment or secret manager. Treat the bundled clients as examples that need hardening before production use, especially status URL validation and restrictions on local file uploads and remote URL downloads.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
references/code-examples/bria_client.py:115
Finding
API Credential Forwarded to an Unvalidated Polling URL<![CDATA[ ## Vulnerability Details **File Location**: `references/code-examples/bria_client.py:115-129` **Additional Locations**: `SKILL.md:214-216`, `references/api-endpoints.md:544-547`, `references/workflows.md:22-25`, `references/workflows.md:115-119`, `references/code-examples/bria_client.ts:182-207`, `references/code-examples/bria_client.sh:124-144` **Vulnerability Type**: Credential disclosure through an untrusted network destination **Risk Level**: High ### Vulnerable Code ```python def _request(self, endpoint: str, data: Dict, wait: bool = True) -> Dict[str, Any]: """Make API request with optional polling.""" url = f"{self.BASE_URL}{endpoint}" response = requests.post(url, json=data, headers=self._headers()) response.raise_for_status() result = response.json() if wait and "status_url" in result: return self._poll(result["status_url"]) return result def _poll(self, status_url: str, timeout: int = 120) -> Dict[str, Any]: """Poll status URL until completion.""" for _ in range(timeout // 2): response = requests.get(status_url, headers=self._headers()) ``` The same pattern is present in the TypeScript workflow: ```typescript const { status_url } = (await res.json()) as BriaResponse; // Poll for result for (let i = 0; i < 60; i++) { const statusRes = await fetch(status_url, { headers: { "api_token": apiKey, "User-Agent": "BriaSkills/1.2.5" } }); ``` ### Technical Analysis The initial request is sent to the expected Bria API host, but the absolute `status_url` returned in the response is trusted without validation. The polling request attaches the Bria API key through the `api_token` header regardless of the polling URL's scheme, hostname, port, or path. Authentication on a legitimate Bria status endpoint is necessary for the declared image-generation functionality. Forwarding that credential to any URL supplied by a response exceeds the minimum privilege needed. Authentica ...[truncated 1272 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse `status_url` before sending any request. 2. Require the `https` scheme. 3. Require an exact approved hostname, such as `engine.prod.bria-api.com`. 4. Reject unexpected ports, embedded credentials, fragments, and non-status paths. 5. Prefer returning a request ID and constructing the status URL locally: ```python from urllib.parse import urlparse ALLOWED_HOST = "engine.prod.bria-api.com" def validate_status_url(status_url: str) -> str: parsed = urlparse(status_url) if parsed.scheme != "https": raise ValueError("Polling URL must use HTTPS") if parsed.hostname != ALLOWED_HOST: raise ValueError("Untrusted polling host") if parsed.port not in (None, 443): raise ValueError("Unexpected polling port") if not parsed.path.startswith("/v2/status/"): raise ValueError("Unexpected polling path") return status_url ``` 6. Disable automatic redirects for authenticated polling requests, or validate every redirect destination before resending credentials. 7. Never forward `api_token` across origins. 8. Apply equivalent validation in the Python, TypeScript, shell, and workflow examples so users do not reproduce the insecure pattern. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
references/code-examples/bria_client.py:87
Finding
Arbitrary URL Retrieval Enables SSRF and External Data Transfer<![CDATA[ ## Vulnerability Details **File Location**: `references/code-examples/bria_client.py:87-103` **Additional Locations**: `references/code-examples/bria_client.py:447-454`, `references/code-examples/bria_client.sh:55-60`, `references/code-examples/bria_client.sh:375` **Vulnerability Type**: Server-side request forgery and unrestricted data upload **Risk Level**: High ### Vulnerable Code ```python @staticmethod def _to_base64(image: str) -> str: """ Resolve an image input to a raw base64 string, downloading URLs if needed. Required for v1 endpoints that only accept base64-encoded images. """ if image.startswith("data:image"): return image.split(",", 1)[1] if image.startswith(("http://", "https://")): resp = requests.get(image) resp.raise_for_status() return base64.b64encode(resp.content).decode("utf-8") if os.path.isfile(image): with open(image, "rb") as f: return base64.b64encode(f.read()).decode("utf-8") return image ``` The downloaded content is subsequently submitted to the external Bria service: ```python return self._request( "/v1/product/lifestyle_shot_by_text", { "file": self._to_base64(image_url), "prompt": prompt, "placement_type": placement_type, }, wait, ) ``` The shell implementation has equivalent behavior and follows redirects: ```bash if [[ "$image" == http://* || "$image" == https://* ]]; then if [[ "$mode" == "data_url" || "$mode" == "base64" ]]; then # Download and base64-encode the URL local b64 b64=$(curl -sL "$image" | base64 | tr -d '\n') ``` ### Technical Analysis The client accepts a caller-controlled URL and retrieves it without restricting the destination. It does not reject loopback, link-local, private, reserved, or cloud metadata addresses. It also lacks response-size limits, content-type validation, file-signature validation, and explicit network timeouts. The shell version fo ...[truncated 2399 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prefer accepting local image files or pre-approved public HTTPS URLs only. 2. Reject plain HTTP unless there is a documented and unavoidable requirement. 3. Resolve the destination hostname and reject all loopback, private, link-local, multicast, reserved, and unspecified IP ranges, including IPv4-mapped IPv6 forms. 4. Explicitly block well-known metadata destinations. 5. Disable redirects, or validate the hostname and resolved IP address after every redirect. 6. Protect against DNS rebinding by connecting to the validated resolved address while preserving the expected TLS hostname. 7. Add strict connection and read timeouts: ```python resp = requests.get( image, timeout=(5, 15), allow_redirects=False, stream=True, ) ``` 8. Enforce a maximum download size while streaming the response. 9. Require an approved image MIME type and validate the actual file signature before encoding or uploading the content. 10. Reject malformed data URLs and limit decoded data size. 11. Document clearly that selected local files and remote images are transmitted to Bria for processing. 12. Apply the same protections to the Python and shell implementations. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:23
Finding
API-Key Presence Check Prints the Secret into Output and Logs<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:23-27` **Vulnerability Type**: Plaintext secret exposure **Risk Level**: Medium ### Vulnerable Code ```markdown ### Step 1: Check if the key exists ```bash echo $BRIA_API_KEY ``` If the output is **not empty**, skip to the next section. ``` ### Technical Analysis The setup procedure prints the complete Bria API key merely to determine whether the environment variable is set. This is unnecessary: variable presence can be tested without revealing its value. In an AI-agent environment, command output may be retained in conversation history, execution traces, CI logs, terminal recordings, or monitoring systems. Consequently, this instruction expands access to the secret beyond the API client and the intended Bria endpoint. The surrounding instructions also tell the user to provide the API key and wait for it. Users should instead be directed to configure the key privately through environment or secret-management facilities, rather than pasting it into a conversation. ### Attack Path 1. A user or agent follows the documented setup procedure. 2. `echo $BRIA_API_KEY` writes the complete credential to standard output. 3. The execution framework, terminal, CI system, or agent transcript records that output. 4. Another party with access to the logs or transcript obtains the key. 5. The party reuses the credential against the Bria API. ### Impact Assessment The exposed credential can be used for operations authorized by the affected Bria account, including unauthorized image-processing requests, account quota consumption, and possible financial cost. This finding does not provide local privilege escalation. Its scope is the Bria account and API permissions associated with the disclosed key. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions Replace the disclosure-prone command with a non-revealing presence check: ```bash if [ -n "${BRIA_API_KEY:-}" ]; then echo "BRIA_API_KEY is set" else echo "BRIA_API_KEY is not set" fi ``` Additional hardening: 1. Do not ask users to paste API keys into chat or agent messages. 2. Instruct users to configure the key directly in an environment variable, protected configuration file, or secret manager. 3. Avoid printing any portion of the key unless an explicitly masked identifier is operationally required. 4. Ensure error messages and debugging output never include request headers. 5. Recommend rotating the credential if it has already appeared in logs or conversation history. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (20)

Ae1

High
Category
analysis-evasion
Content
- **[TypeScript Client](references/code-examples/bria_client.ts)** — Typed Node.js client
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- **[Bash/curl Reference](references/code-examples/bria_client.sh)** — Shell functions for all endpoints
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Lp3

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding
The skill instructs use of shell, environment-variable access, and outbound network calls, but it declares no explicit tool scope or permission boundaries. That increases the chance an agent will invoke this skill with broader-than-necessary capabilities, making unintended secret access or external requests harder to constrain and audit.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The description says the skill triggers on broad concepts like AI image generation, controllable editing, background removal, or visual asset creation, without clear activation boundaries. In an agent environment, this can cause over-broad automatic invocation, increasing the chance of unnecessary external API use, secret handling, or user data transmission in contexts where the user did not clearly request Bria.

External Transmission

Medium
Category
Data Exfiltration
Content
### Generate an Image (FIBO)

```bash
curl -X POST "https://engine.prod.bria-api.com/v2/image/generate" \
  -H "api_token: $BRIA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "User-Agent: BriaSkills/1.2.5" \
Confidence
94% confidence
Finding
This skill sends prompts, image URLs, and an API token to an external service, which is an external transmission by design. In context this is expected functionality, but it is still security-relevant because user-provided images or sensitive prompts may be transmitted off-platform, and the examples normalize direct shell-based exfiltration paths using secrets from environment variables.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The API reference instructs callers to send image URLs, base64 image data, prompts, masks, and other editing inputs to Bria's external service but does not warn users that their content leaves the local environment. This can lead developers or end users to unknowingly transmit sensitive or proprietary images, prompts, and metadata to a third-party processor, creating privacy, compliance, and data-handling risk.

External Transmission

Medium
Category
Data Exfiltration
Content
def _request(self, endpoint: str, data: Dict, wait: bool = True) -> Dict[str, Any]:
        """Make API request with optional polling."""
        url = f"{self.BASE_URL}{endpoint}"
        response = requests.post(url, json=data, headers=self._headers())
        response.raise_for_status()
        result = response.json()
Confidence
91% confidence
Finding
This client transmits user-supplied prompts, instructions, image URLs, and potentially local file contents or base64-encoded images to an external Bria API endpoint. In this skill’s context that is expected functionality, but it is still a real data-exfiltration boundary because local files and arbitrary image URLs are accepted without guardrails, so sensitive data could be sent off-host unintentionally.

Indirect Prompt Extraction

Medium
Category
System Prompt Leakage
Content
Add a new object to an image using natural language.

        Args:
            image_url: Source image URL or base64
            instruction: What and where to add (e.g., "Place a red vase on the table")
            wait: Wait for completion
Confidence
85% confidence
Finding
Skill contains patterns that could indirectly extract system prompts through rephrasing, translation, summarization, or side-channel techniques.

Indirect Prompt Extraction

Medium
Category
System Prompt Leakage
Content
Add a new object to an image using natural language.

        Args:
            image_url: Source image URL or base64
            instruction: What and where to add (e.g., "Place a red vase on the table")
            wait: Wait for completion
Confidence
85% confidence
Finding
Skill contains patterns that could indirectly extract system prompts through rephrasing, translation, summarization, or side-channel techniques.

Indirect Prompt Extraction

Medium
Category
System Prompt Leakage
Content
Add a new object to an image using natural language.

        Args:
            image_url: Source image URL or base64
            instruction: What and where to add (e.g., "Place a red vase on the table")
            wait: Wait for completion
Confidence
85% confidence
Finding
Skill contains patterns that could indirectly extract system prompts through rephrasing, translation, summarization, or side-channel techniques.

Indirect Prompt Extraction

Medium
Category
System Prompt Leakage
Content
Convert a sketch or line drawing to a photorealistic image.

        Args:
            image_url: Sketch image URL or base64
            prompt: Optional description to guide the conversion
            wait: Wait for completion
Confidence
85% confidence
Finding
Skill contains patterns that could indirectly extract system prompts through rephrasing, translation, summarization, or side-channel techniques.

External Transmission

Medium
Category
Data Exfiltration
Content
bria_check_api_key || return 1

  local response
  response=$(curl -s -X POST "${BRIA_BASE_URL}${endpoint}" \
    -H "api_token: ${BRIA_API_KEY}" \
    -H "Content-Type: application/json" \
    -H "User-Agent: ${BRIA_USER_AGENT}" \
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
This shell script sends request payloads to the Bria API via curl, and those payloads can include user prompts, remote image URLs, or base64-encoded local image contents resolved elsewhere in the script. While the script's comments describe its purpose, there is no runtime confirmation or explicit user-facing warning that local image data and prompts are being uploaded to an external service.

External Transmission

Medium
Category
Data Exfiltration
Content
bria_request "/v2/structured_instruction/generate" "$data"
}

# ==================== Raw curl Examples ====================

# The following are standalone curl commands that can be copied directly.
# They don't use the helper functions above.
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The client accepts a local file path, reads the file from disk, base64-encodes it, and sends it to a third-party API. In an agent/skill context, this can cause unintended exfiltration of local images or nearby sensitive files if untrusted input is allowed to control the image parameter and users are not clearly warned that local files will be uploaded off-host.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The examples send user prompts and generated-image workflow data to Bria-hosted external endpoints, but the documentation does not clearly warn that prompts may contain sensitive business or personal information and will leave the local environment. In a skill designed for image generation this transmission is expected, but the lack of disclosure can still cause unintentional data exposure if users paste confidential prompts or asset references into these workflows.

External Transmission

Medium
Category
Data Exfiltration
Content
async function generateOne(prompt: string): Promise<string> {
    return withLimit(async () => {
      // Launch request
      const res = await fetch("https://engine.prod.bria-api.com/v2/image/generate", {
        method: "POST",
        headers: { "api_token": apiKey, "Content-Type": "application/json", "User-Agent": "BriaSkills/1.2.5" },
        body: JSON.stringify({ prompt, aspect_ratio: aspectRatio })
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The pipeline examples describe sending image URLs and edited assets to external background-removal and lifestyle-editing endpoints without warning that image contents are processed by a third party. Because images may contain proprietary products, personal data, or sensitive visual information, users could unknowingly disclose protected content during automated pipeline use.

Missing User Warnings

Low
Confidence
91% confidence
Finding
The helper accepts arbitrary http(s) URLs and fetches them with curl, then may re-encode and forward the content onward. If untrusted input controls the URL, this can be abused for server-side request forgery behavior, internal network probing, or unintended retrieval of sensitive resources, especially when run in privileged or network-reachable environments.

Missing User Warnings

Low
Confidence
76% confidence
Finding
The constructor pulls credentials from BRIA_API_KEY and the headers method attaches that secret to outbound requests. This is sensitive credential handling, and the disclosure is limited to code comments rather than a user-facing warning or runtime notice.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
references/code-examples/bria_client.ts:115