Skip to content

Security: SSRF/DoS via show_image, Docker secret exposure, and unbounded paid tasks #23

Description

@diesdaas

Summary

A static review of current main at commit 8bc14db found four security-relevant issues. No live PiAPI jobs, exploit traffic, or customer data were used.

The server currently uses stdio, so exploitation requires an MCP client that is permitted to invoke the affected tools; it is not an unauthenticated network service as shipped. This still matters for LLM-driven clients because tool calls may be influenced by untrusted content or prompt injection.

1. High: SSRF and internal-data disclosure through show_image

show_image accepts any syntactically valid URL and passes it directly to fastmcp.imageContent().

In the dependency version selected by the current range, the URL is fetched from the MCP host, the complete response is buffered, file-type detection is performed, and the bytes are returned as base64. There is no application-level protection against:

  • loopback, RFC1918/private, link-local, or cloud-metadata addresses;
  • DNS rebinding or redirects to a prohibited destination;
  • oversized or indefinitely streaming responses;
  • non-image response bodies.

A caller able to invoke this tool could therefore request internal HTTP endpoints and receive their response bytes, or exhaust process memory/availability.

Suggested mitigation:

  • Prefer removing this generic fetch tool or restrict it to an explicit CDN/domain allowlist.
  • Permit HTTPS only.
  • Resolve DNS and reject loopback/private/link-local/metadata IPv4 and IPv6 addresses before each request and after every redirect.
  • Handle redirects manually and revalidate every hop.
  • Enforce a short timeout and a streaming byte limit.
  • Reject responses whose content type and magic bytes are not an approved image type.

2. High reachability: vulnerable file-type parser in the same path

A fresh production dependency resolution selects fastmcp@1.27.7 and file-type@20.5.0. The latter processes the attacker-controlled bytes fetched by show_image and is affected by:

Upgrade to a FastMCP release that resolves file-type >=21.3.2, commit a lockfile, and retain the input/network limits above as defense in depth.

3. High: PIAPI_API_KEY is copied into the final Docker image

The Dockerfile contains:

COPY .env ./

The repository has no .dockerignore. A successful build therefore stores the API key in the final image and its layers, where anyone with image/container access can extract it.

Suggested mitigation:

  • Remove COPY .env ./ and exclude .env from the build context.
  • Inject PIAPI_API_KEY only at runtime using the deployment platform's secret mechanism.
  • Rotate any key that has already been included in a built or distributed image.

4. High operational/financial risk: unbounded paid-task execution

At the reviewed commit, 109 catalog tools plus 23 hand-written tools are registered. Nearly every generation tool immediately reaches createTask(), which submits a PiAPI job.

There is no server-side default-deny switch, tool allowlist, user confirmation, spend/call budget, rate limit, concurrency limit, or idempotency protection. According to PiAPI billing documentation, quotas are deducted and frozen when a job is submitted.

A compromised or prompt-injected MCP client could therefore create repeated paid workloads and drain credits.

Suggested mitigation:

  • Default paid task creation to disabled, for example PIAPI_ENABLE_PAID_TASKS=false.
  • Add a per-deployment tool allowlist.
  • Require explicit confirmation or a short-lived approval token for task creation.
  • Add per-session and daily call/spend limits plus a concurrency cap.
  • Use idempotency keys where supported and expose tools with accurate destructive/non-idempotent annotations.

Requested action

Please treat these as security fixes before recommending unattended or shared-agent deployment. Regression tests should cover private-network URLs, redirect chains, oversized/malformed bodies, missing runtime approval, and accidental secret inclusion in Docker images.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions