← MCP server and skill grades

heroku-mcp-server

heroku/heroku-mcp-server

D
Type
MCP server
Scanned
Oct 29, 2026
Version
970528fc07bc
Files read
85

This MCP server lets AI coding agents manage Heroku applications, databases, add-ons, pipelines, and deployments using the Heroku CLI and Platform API. Its biggest risks are that prompt-injected tool arguments can execute local commands or read local files via psql, pack and upload arbitrary local directories during deployment, or overwrite local files via AI inference output.

What it can reach

Shell commands
Spawns the Heroku CLI REPL (via npx or local heroku binary), runs git commands in workspace directories, and invokes local psql through heroku pg:psql.
Files
Reads and archives local directories for app deployment, reads local SQL files for pg_psql, and writes temporary and user-specified output files for AI inference.
Network
Connects to api.heroku.com, devcenter.heroku.com, S3 source upload URLs, build stream URLs, and Heroku Rendezvous TLS endpoints.
Secrets
Reads HEROKU_API_KEY from the environment and uses existing Heroku CLI authentication sessions.

Findings

3 high1 medium1 low
  1. HighLocal command execution and arbitrary file read via pg_psql tool arguments

    src/tools/data.ts:15

    The pg_psql tool passes the user-supplied 'file' and 'command' arguments to 'heroku pg:psql', which runs the local 'psql' client. An attacker using prompt injection can pass a local file path in 'file' to read files from the user's machine, or use psql backslash meta-commands (such as '\! <cmd>' or '\copy') in 'command' or 'file' to execute arbitrary shell commands locally once connected to a Heroku Postgres database.

    Fix: Remove the 'file' parameter from pg_psql, disallow psql backslash meta-commands in 'command', or pass '--set=ON_ERROR_STOP=1' without allowing meta-command execution.

  2. HighArbitrary local directory upload via unvalidated rootUri in deploy_to_heroku

    src/tools/deploy-to-heroku.ts:289

    The deploy_to_heroku tool accepts any filesystem path in 'rootUri' and archives all files in that directory into a tarball that is uploaded to Heroku. Because 'appJson' can be provided inline, 'rootUri' does not need to contain an app.json file. Through prompt injection, an attacker can point 'rootUri' at sensitive folders (such as ~/.ssh or ~/.aws) to upload and exfiltrate their contents to a Heroku app.

    Fix: Restrict 'rootUri' to an explicitly configured workspace root directory and require user confirmation before packaging and uploading local directories.

  3. HighArbitrary local file write via output parameter in make_ai_inference

    src/tools/ai.ts:38

    When '@heroku/plugin-ai' is installed, the make_ai_inference tool exposes an 'output' parameter that passes '--output' to 'heroku ai:agents:call'. A prompt-injected agent can set 'output' to any path on the user's filesystem and control the model prompt, allowing it to overwrite sensitive files such as shell profiles, SSH keys, or scripts.

    Fix: Remove the 'output' file path parameter from make_ai_inference and return the inference output solely through the MCP tool response.

  4. MediumUnpinned runtime download and execution of heroku@latest via npx

    src/repl/heroku-cli-repl.ts:126

    Before checking for an installed 'heroku' CLI binary, the server checks if 'npx' exists and spawns 'npx -y heroku@latest repl'. Because npx is present in standard Node.js environments, the server downloads and executes the latest unpinned 'heroku' package from npm at runtime with HEROKU_API_KEY in its environment.

    Fix: Prefer the locally installed 'heroku' CLI binary first, and if npx fallback is retained, pin to a specific verified version rather than 'heroku@latest'.

  5. LowUnencoded path parameters in Heroku Platform API requests

    src/services/app-service.ts:20

    Service methods interpolate 'appIdentity', 'buildIdentity', and 'dynoIdentity' directly into API URL paths without URL-encoding or strict character validation. In deploy_to_heroku and deploy_one_off_dyno, the 'name' parameter is only validated for length (5 to 30 characters), allowing path traversal segments ('../') in authenticated requests to api.heroku.com.

    Fix: Validate app names against Heroku's naming pattern (/^[a-z][a-z0-9-]{1,28}[a-z0-9]$/) and wrap path segments with encodeURIComponent().