Back to skill

Security audit

Bria Ai

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent Bria image API helper, but it handles credentials and user images with insecure local storage and insufficient destination controls.

Review this skill before installing on shared or sensitive machines. Use it only with non-confidential images, ensure ~/.bria and ~/.bria/credentials are locked down to the current user, avoid running it in environments where BRIA_AUTH_BASE or BRIA_API_BASE could be set unexpectedly, and rotate Bria credentials if they may have been stored with permissive permissions.

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_auth.sh:40
Finding
Credential Files Are Created Without Restrictive Permissions<![CDATA[ ## Vulnerability Details **File Location**: `references/code-examples/bria_auth.sh`, lines 40–41 and 73–76 **Vulnerability Type**: Plaintext credentials stored with permissions inherited from the process umask **Risk Level**: High ### Vulnerable Code ```bash mkdir -p ~/.bria printf 'access_token=%s\nrefresh_token=%s\n' "$BRIA_ACCESS_TOKEN" "$REFRESH_TOKEN" > "$HOME/.bria/credentials" ``` The API token is subsequently written through another temporary file without explicitly setting its permissions: ```bash if [ -n "$BRIA_API_KEY" ]; then grep -v '^api_token=' "$HOME/.bria/credentials" > "$HOME/.bria/credentials.tmp" 2>/dev/null || true printf 'api_token=%s\n' "$BRIA_API_KEY" >> "$HOME/.bria/credentials.tmp" mv "$HOME/.bria/credentials.tmp" "$HOME/.bria/credentials" fi ``` ### Technical Analysis The helper stores OAuth access tokens, refresh tokens, and the Bria API token in a plaintext file under the user's home directory. Reading and caching Bria credentials is relevant to the declared functionality, but the implementation does not establish minimum required filesystem permissions. Neither `~/.bria` nor `~/.bria/credentials` is created with an explicit restrictive mode. Their permissions therefore depend on the invoking process's umask. For example, with a typical `022` umask, the directory may be created as `0755` and the credential file as `0644`, allowing other local users to read the tokens. The later `credentials.tmp` replacement has the same weakness. Because `mv` replaces the original file with the newly created temporary file, this operation can discard secure permissions that may previously have been applied to `credentials`. ### Attack Path 1. A user invokes `bria_auth` on a multi-user system while using a permissive umask. 2. The helper creates `~/.bria/credentials` without an explicit `0600` mode. 3. The file contains the user's OAuth access token and refresh token. 4. After introspection, the same file also contains the B ...[truncated 650 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Establish a restrictive umask before creating credential material: ```bash umask 077 ``` 2. Create the credential directory with an explicit mode: ```bash install -d -m 700 "$HOME/.bria" ``` 3. Create replacement files securely and enforce mode `0600`: ```bash credential_tmp=$(mktemp "$HOME/.bria/credentials.XXXXXX") || return 1 chmod 600 "$credential_tmp" || { rm -f "$credential_tmp" return 1 } ``` 4. Write all credential fields to the secure temporary file and atomically rename it into place. 5. Apply `chmod 600 "$HOME/.bria/credentials"` after replacement as defense in depth. 6. Install cleanup traps so temporary credential files are removed on interruption or failure. 7. Where supported, use an operating-system credential store instead of a plaintext file. 8. Document token revocation and rotation procedures for users who may already have created permissive credential files. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
references/code-examples/bria_client.sh:92
Finding
Credentials and User Images Can Be Sent to Untrusted Destinations<![CDATA[ ## Vulnerability Details **File Location**: `references/code-examples/bria_auth.sh`, lines 10, 13–14, 30–32, and 59–60; `references/code-examples/bria_client.sh`, lines 14, 77–82, and 92–99 **Vulnerability Type**: Unvalidated network destination and credential forwarding **Risk Level**: High ### Vulnerable Code The authentication destination can be overridden through the environment: ```bash BRIA_AUTH_BASE="${BRIA_AUTH_BASE:-https://engine.prod.bria-api.com}" ``` Device authorization, token exchange, and token introspection use that override: ```bash DEVICE_RESPONSE=$(curl -s -X POST "${BRIA_AUTH_BASE}/v2/auth/device/authorize" \ -H "Content-Type: application/json") ``` ```bash TOKEN_RESPONSE=$(curl -s -X POST "${BRIA_AUTH_BASE}/v2/auth/token" \ -d "grant_type=urn:ietf:params:oauth:grant-type:device_code" \ -d "device_code=$DEVICE_CODE") ``` ```bash INTROSPECT=$(curl -s -X POST "${BRIA_AUTH_BASE}/v2/auth/token/introspect" \ -d "token=$BRIA_ACCESS_TOKEN") ``` The main API destination is similarly environment-controlled: ```bash BRIA_API_BASE="${BRIA_API_BASE:-https://engine.prod.bria-api.com}" ``` The API key, prompts, and base64-encoded local images are sent to that destination: ```bash http_code=$(curl -s -o "$result" -w '%{http_code}' -X POST \ "${BRIA_API_BASE}${endpoint}" \ -H "api_token: $BRIA_API_KEY" \ -H "Content-Type: application/json" \ -H "User-Agent: $BRIA_USER_AGENT" \ -d @"$payload") ``` The client also forwards the API key to a server-provided polling URL without validating its scheme or origin: ```bash status_url=$(printf '%s' "$body" | sed -n 's/.*"status_url" *: *"\([^"]*\)".*/\1/p') if [ -n "$status_url" ]; then i=0 while [ "$i" -lt 30 ]; do sleep 3 poll=$(curl -s "$status_url" \ -H "api_token: $BRIA_API_KEY" \ -H "User-Agent: $BRIA_USER_AGENT") ``` ### Technical Analysis Configurable service endpoints can be useful for legitimate testing, but these helpers do not distinguish ...[truncated 2397 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin production authentication and API requests to the documented origin: ```bash readonly BRIA_ORIGIN="https://engine.prod.bria-api.com" ``` 2. Do not honor endpoint override variables when production credentials are loaded. 3. If endpoint overrides are required for development, require an explicit development mode and separate test credentials. Display a warning and refuse to load `~/.bria/credentials` in that mode. 4. Parse every polling URL and require: - The `https` scheme. - An exact approved hostname. - An approved port. - An expected status endpoint path. 5. Never forward the API key across origins or through redirects. Use curl options that prevent unsafe redirect behavior and explicitly reject unexpected response URLs. 6. Validate `endpoint` arguments as relative paths from an allowlist rather than concatenating arbitrary caller input. 7. Fail closed when URL parsing or origin validation cannot be completed. 8. Document that prompts and local images are transmitted to Bria after user authorization. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
references/code-examples/bria_client.sh:39
Finding
Predictable Shared Temporary Files Permit Symlink Attacks and Image Disclosure<![CDATA[ ## Vulnerability Details **File Location**: `references/code-examples/bria_client.sh`, lines 39–70 and 76–86 **Vulnerability Type**: Predictable temporary files in a shared directory **Risk Level**: Medium ### Vulnerable Code The request payload uses a predictable PID-based name: ```bash # --- Build JSON payload to temp file (safe for large images) --- payload="/tmp/bria_payload_$$.json" if [ -z "$image" ]; then printf '{' > "$payload" elif printf '%s' "$image" | grep -qE '^https?://'; then if [ "$key" = "images" ]; then printf '{"images": ["%s"]' "$image" > "$payload" else printf '{"%s": "%s"' "$key" "$image" > "$payload" fi else [ ! -f "$image" ] && { echo "ERROR: File not found: $image" >&2; return 1; } if [ "$key" = "images" ]; then printf '{"images": ["' > "$payload" else printf '{"%s": "' "$key" > "$payload" fi base64 < "$image" | tr -d '\n' >> "$payload" if [ "$key" = "images" ]; then printf '"]' >> "$payload" else printf '"' >> "$payload" fi fi if [ -n "$extra" ]; then if [ -z "$image" ]; then printf '%s' "$extra" >> "$payload" else printf ', %s' "$extra" >> "$payload" fi fi printf '}' >> "$payload" ``` The API response uses the same unsafe naming pattern: ```bash result="/tmp/bria_result_$$.json" http_code=$(curl -s -o "$result" -w '%{http_code}' -X POST \ "${BRIA_API_BASE}${endpoint}" \ -H "api_token: $BRIA_API_KEY" \ -H "Content-Type: application/json" \ -H "User-Agent: $BRIA_USER_AGENT" \ -d @"$payload") body=$(cat "$result") rm -f "$payload" "$result" ``` ### Technical Analysis The filenames are based only on the process ID and are placed directly in the globally shared `/tmp` directory. Process IDs are predictable, and the files are opened using normal shell redirection or curl output handling without exclusive creation or symlink protection. A local attacker can pre-create a symbolic link at an anticipated pathname. When the victim invokes `bria_call`, th ...[truncated 1816 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Set a restrictive umask before handling image data: ```bash umask 077 ``` 2. Create a private temporary directory and files with `mktemp`: ```bash tmp_dir=$(mktemp -d "${TMPDIR:-/tmp}/bria.XXXXXX") || return 1 payload=$(mktemp "$tmp_dir/payload.XXXXXX.json") || { rm -rf "$tmp_dir" return 1 } result=$(mktemp "$tmp_dir/result.XXXXXX.json") || { rm -rf "$tmp_dir" return 1 } ``` 3. Verify that the temporary directory is owned by the current user and has mode `0700`. 4. Install cleanup handling immediately after creation: ```bash trap 'rm -rf -- "$tmp_dir"' EXIT HUP INT TERM ``` 5. Avoid reusing existing paths and do not use PID-only names. 6. Ensure all early-return paths remove temporary artifacts. 7. Where practical, stream request bodies and responses without writing sensitive image data to shared storage. 8. Do not weaken permissions when replacing or recreating temporary files. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • 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 (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The core behavior is generally aligned with a Bria image API client: it builds JSON payloads for image generation/edit operations, uploads images as base64 or URL references, calls Bria API endpoints, and returns result URLs. However, the description specifically claims OAuth device flow authentication and broad endpoint/trigger coverage, which are not implemented in this code chunk. Instead, the code relies on a preexisting API token loaded from an environment variable or ~/.bria/credentials. Because the declared description materially overstates authentication behavior and supported trigger/endpoint implementation compared with the supplied code, this is a mismatch.

Ae1

High
Category
analysis-evasion
Content
- **[Auth Helper (bria_auth.sh)](references/code-examples/bria_auth.sh)** — `bria_auth` and `bria_introspect` functions
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill clearly instructs use of shell commands (`bash`, `source`, file reads, and helper scripts) but does not declare any tool scope or allowed-tools restrictions. That creates unnecessary execution latitude for an agent and makes review and policy enforcement harder, especially because the skill also handles credentials and network calls.

Session Persistence

Medium
Category
Rogue Agent
Content
name: bria-ai
description: >
  Bria.ai image API — generate from text prompts, edit with natural language,
  remove backgrounds for transparent PNGs, and create product lifestyle shots.
  Authenticates via OAuth device flow, caches credentials in ~/.bria/credentials,
  calls 20+ endpoints. Commercially safe, royalty-free.
  Triggers on: remove background, transparent PNG, cutout, generate image, create banner,
Confidence
89% confidence
Finding
The skill advertises session persistence by caching authentication material in `~/.bria/credentials`, which can outlive the intended session and be reused silently. In an agent context, persistent authentication increases blast radius if the host is shared, compromised, or if future tasks inherit access without fresh user intent.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill states that OAuth credentials and API keys are cached in `~/.bria/credentials` but gives no warning about persistence, local exposure, or file-permission expectations. Persisted tokens on disk increase the risk of credential theft from other local processes, users, backups, or accidental disclosure.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill instructs sending local image files and remote URLs to a third-party API without an explicit privacy or data-transfer warning. Users may unknowingly upload sensitive images, internal URLs, or proprietary content to an external service, creating confidentiality and compliance risks.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
This markdown file documents mandatory authentication headers and repeated API calls to a remote service, and many endpoints accept image URLs or base64 image data. The document does not include any user-facing warning that submitted images and metadata are sent to an external service, which is relevant to privacy and data-handling expectations.

External Transmission

Medium
Category
Data Exfiltration
Content
local i=0
  while [ "$i" -lt 60 ]; do
    sleep "$INTERVAL"
    TOKEN_RESPONSE=$(curl -s -X POST "${BRIA_AUTH_BASE}/v2/auth/token" \
      -d "grant_type=urn:ietf:params:oauth:grant-type:device_code" \
      -d "device_code=$DEVICE_CODE")
    BRIA_ACCESS_TOKEN=$(printf '%s' "$TOKEN_RESPONSE" | sed -n 's/.*"access_token" *: *"\([^"]*\)".*/\1/p')
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Session Persistence

Medium
Category
Rogue Agent
Content
BRIA_ACCESS_TOKEN=$(printf '%s' "$TOKEN_RESPONSE" | sed -n 's/.*"access_token" *: *"\([^"]*\)".*/\1/p')
    if [ -n "$BRIA_ACCESS_TOKEN" ]; then
      REFRESH_TOKEN=$(printf '%s' "$TOKEN_RESPONSE" | sed -n 's/.*"refresh_token" *: *"\([^"]*\)".*/\1/p')
      mkdir -p ~/.bria
      printf 'access_token=%s\nrefresh_token=%s\n' "$BRIA_ACCESS_TOKEN" "$REFRESH_TOKEN" > "$HOME/.bria/credentials"
      echo "AUTHENTICATED"
      bria_introspect
Confidence
95% confidence
Finding
The skill persists session material under ~/.bria, and the subsequent write stores bearer credentials that can be reused by anyone who gains local read access. Because this is an auth helper script for an API skill, session persistence increases risk by making compromise durable across shell sessions and potentially exposing commercial API access and billing-linked operations.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script writes access and refresh tokens to ~/.bria/credentials in plaintext without setting restrictive permissions or clearly disclosing that long-lived credentials will be stored locally. On multi-user systems or in environments with lax default umask settings, other local processes or users may be able to read or recover these tokens and reuse the session.

External Transmission

Medium
Category
Data Exfiltration
Content
fi
  [ -z "$BRIA_ACCESS_TOKEN" ] && { echo "NO_CREDENTIALS"; return 1; }

  INTROSPECT=$(curl -s -X POST "${BRIA_AUTH_BASE}/v2/auth/token/introspect" \
    -d "token=$BRIA_ACCESS_TOKEN")

  BILLING_STATUS=$(printf '%s' "$INTROSPECT" | sed -n 's/.*"billing_status" *: *"\([^"]*\)".*/\1/p')
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
91% confidence
Finding
When the token is inactive, the script truncates $HOME/.bria/credentials, which is a destructive file operation affecting persisted authentication data. The only visible output is TOKEN_EXPIRED after the deletion, so the user is not warned beforehand that local credentials will be removed.

External Transmission

Medium
Category
Data Exfiltration
Content
# --- API call ---
  result="/tmp/bria_result_$$.json"
  http_code=$(curl -s -o "$result" -w '%{http_code}' -X POST \
    "${BRIA_API_BASE}${endpoint}" \
    -H "api_token: $BRIA_API_KEY" \
    -H "Content-Type: application/json" \
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

Low
Confidence
84% confidence
Finding
This markdown describes operations such as background removal, object erasure, foreground erasure, and background replacement that materially change user-provided images. Although these are core features, the document does not warn users to preserve originals or note that outputs may overwrite intended visual content if used incautiously.

Missing User Warnings

Low
Confidence
82% confidence
Finding
The bria_introspect function sends the user's access token to a remote introspection endpoint via curl. While this is functionally expected for token verification, the script provides no visible notice at execution time that an existing credential will be transmitted to the service for validation.

Static analysis

No suspicious patterns detected.