STUPID-2026-0120

Aider leaks model-provider API keys to child processes spawned via /run, /test, lint commands, and /git

4.7medium
August 31, 2026VerifiedReproducible
  1. Instruction given

    None specific to a coding task — the exposure exists whenever Aider is running with a model-provider credential set (e.g. `OPENAI_API_KEY`) in its process environment and the user invokes `/run`, `/test`, a configured lint command, or `/git`.

  2. Expected behavior

    Commands Aider shells out to on the user's behalf — test runners, linters, and git — have no legitimate need for the model-provider credential Aider itself uses to talk to the LLM API. Aider should pass those child processes a restricted environment that excludes provider credentials, not the full process environment.

  3. Actual behavior

    In `aider/run_cmd.py`, `run_cmd_subprocess()` calls `subprocess.Popen()` without supplying a restricted `env`, so `/run`, `/test`, and configured lint commands inherit Aider's complete process environment, credentials included. Separately, Aider's `/git` handling builds `env = dict(subprocess.os.environ)` and passes that unmodified copy to the git subprocess. Both paths were traced to specific functions and cited against commit `5dc9490bb35f9729ef2c95d00a19ccd30c26339c`. The reporter demonstrated it directly: running Aider with `OPENAI_API_KEY=aider-provider-sentinel` set, then issuing `/run test -n "$OPENAI_API_KEY" && echo OPENAI_API_KEY_PRESENT` inside the session, confirms the credential is visible to the spawned process.

  4. Damage

    Filed by the reporting user (younaman) with a specific commit reference, two distinct code paths identified, and an exact reproduction command — no maintainer response recorded as of publication. No confirmed real-world exfiltration was reported. The exposure requires a test command, lint config, or git hook that an attacker controls or has compromised (e.g. via a malicious dependency or a poisoned repository) to actually read and exfiltrate the inherited variable, which narrows but does not eliminate the risk: any of those already run with the user's authority, and a leaked model-provider key adds billable API access under that identity as a distinct, separately monetizable outcome of running untrusted repository content.

A GitHub issue filed against Aider-AI/aider identifies two places where Aider hands its own process environment — model-provider credentials like `OPENAI_API_KEY` included — to child processes that have no need for them. `run_cmd_subprocess()` in `aider/run_cmd.py`, used by `/run`, `/test`, and configured lint commands, calls `subprocess.Popen()` without a restricted `env` argument, so those commands inherit everything Aider itself was started with. Aider's `/git` handling does the same thing more explicitly, building `env = dict(subprocess.os.environ)` and passing the unmodified copy straight to the git subprocess. The reporter traced both paths to specific functions against a cited commit and demonstrated the leak directly: setting `OPENAI_API_KEY=aider-provider-sentinel` and then running `/run test -n "$OPENAI_API_KEY" && echo OPENAI_API_KEY_PRESENT` from inside an Aider session confirms the credential reaches the child process. A test suite, lint command, or git hook controlled by a malicious dependency or a poisoned repository — content that already runs with the user's authority the moment Aider shells out to it — gains a second, separately monetizable payoff: the user's model-provider API key, valid for billable requests under that identity. As of publication the issue carries no maintainer response.

Classification

Agent
Aider
Root cause
Other
Domain
Security

Related incidents

Get told when an agent breaks something

We document AI agent failures daily, severity-scored against a published scale. When one lands at 7.0 or above — deleted data, leaked secrets, broken production — you get an email with the source. When nothing does, you get nothing.

This database is callable over MCP — query it from inside your agent.