STUPID-2026-0160

Aider's shell-command confirmation silently defaults to "yes" when stdin is closed, letting model-suggested commands run unconfirmed

8.0high
November 6, 2026Repro reported

Why 8/10

A PoC-demonstrated bypass that lets a model-suggested shell command run with no user confirmation on any non-interactive Aider invocation with closed stdin. Not yet vendor-confirmed or patched; no reported real-world exploitation, so scored as a demonstrated flaw rather than a realized breach.

Scope
3/4
A whole machine or drive, an organisation's production system or data, or many credentials
Recoverability
3/3
Permanently lost or irreversible, including data that was exposed
Did it happen
1/2
Demonstrated (proof of concept, reproduction, controlled test or near-miss) with no real victim reported
Beyond the user
1/1
Production systems, customers or third parties, or credentials and sensitive personal data

The score is the sum of these four factors. How each factor is scored · scored 2026-11-09

Status and what to do

Affected
aider-chat up to v0.86.2 / commit 253f0368b873ba30d8ee26e463718f0c03614ddf, run non-interactively without --yes-always.
Fix status
Open · PR #5957 proposes a fix; not merged or confirmed by a maintainer as of publication.
Mitigation
Never run Aider non-interactively (CI, scripts, piped input) with stdin closed unless you already trust it to auto-approve every command via --yes-always; otherwise ensure stdin stays open and interactive so a closed-stdin EOF cannot silently stand in for an explicit "yes".
Last reviewed
2026-11-09 · Report a correction to this record
  1. Instruction given

    N/A — this is a flaw in Aider's own confirmation mechanism for model-suggested shell commands, not a task a user asked the agent to perform. It triggers whenever Aider runs non-interactively (e.g. piped input, CI, or any wrapper that closes stdin) without `--yes-always`.

  2. Expected behavior

    When `confirm_ask()` hits an `EOFError` (stdin closed or exhausted) while confirming a model-proposed shell command, it should deny the action — especially when `explicit_yes_required=True` is set, as Aider's own shell- command gate requests — rather than falling back to the prompt's default answer of "yes".

  3. Actual behavior

    In `aider/io.py`, `confirm_ask()` maps an `EOFError` to the prompt's `default` value, which is `"y"`, even when `explicit_yes_required=True`. `handle_shell_commands()` in `aider/coders/base_coder.py` does not override that default to `"n"` before calling it. The reporter's proof of concept pointed Aider at a local test server returning a bash block containing `touch /tmp/aider-poc-marker`: piping explicit `n` responses correctly blocked the command, but running the identical invocation with stdin closed (`</dev/null`) printed a `[Yes]` prompt, ran the command anyway, and exited 0 — with no `y` ever entered. The same silent-default-to-yes path also affects Aider's prompts for editing files outside the chat and for creating new files.

  4. Damage

    The reporter (EddieMurphy89) filed exact reproduction steps, the two affected code paths, and a CWE-636/CWE-693 classification, against `aider-chat` up to v0.86.2 (commit 253f0368b873ba30d8ee26e463718f0c03614ddf). Exploiting it for real harm needs a second ingredient — something that gets the model to propose a destructive or exfiltrating command in the first place, e.g. a poisoned repo file or fetched page — at which point this bug removes the one confirmation step standing between that suggestion and execution, with the user's own privileges. The repository has no `SECURITY.md` or private disclosure channel, so the report was filed as a public issue. A fix, PR #5957, is open but unmerged; the issue carries no maintainer comment or confirmation as of publication.

Full write-up

A security researcher (EddieMurphy89) reported that Aider's confirmation prompt for model-suggested shell commands can be bypassed simply by closing stdin. Aider's confirm_ask() helper in aider/io.py treats an EOFError — raised when stdin is closed, redirected from empty input, or the terminal session has ended — as equivalent to accepting the prompt's default answer, which is "y", even when the caller set explicit_yes_required=True to demand an explicit response. handle_shell_commands() in aider/coders/base_coder.py, the function that gates a model-proposed shell command behind that same confirmation, never overrides the default to "n". The result: a bash command the model suggests runs on the host with no human ever having said yes.

The reporter's proof of concept made the gap concrete. Pointing Aider at a local OpenAI-compatible test server that always replies with a bash block containing touch /tmp/aider-poc-marker, and piping explicit n answers into Aider, correctly left the marker file uncreated — the confirmation worked as intended. Running the exact same invocation with stdin closed (</dev/null) instead printed [Yes], executed touch /tmp/aider-poc-marker && echo ran, exited 0, and left the marker file on disk — with zero characters of input ever read. The same unconditional default-to-yes path also governs Aider's prompts for editing files outside the chat and creating new files. Filed against aider-chat through v0.86.2 with CWE-636 (Not Failing Securely) and CWE-693 (Protection Mechanism Failure) citations and two concrete remediations, the issue remains open with an unmerged fix PR and no maintainer confirmation.

Classification

Agent
Aider
Root cause
Logic Error
Domain
Security
OWASP Agentic Top 10 (our mapping)
ASI05 Unexpected Code Execution (RCE) list
MIT AI Risk Repository (our mapping)
2.2 AI system security vulnerabilities and attacks taxonomy

Related incidents

Cite this record
StupidLLM. "STUPID-2026-0160: Aider's shell-command confirmation silently defaults to "yes" when stdin is closed, letting model-suggested commands run unconfirmed." AI Agent Incident Database, 2026. https://www.stupidllm.com/incident/STUPID-2026-0160/ (accessed 2026-11-09). CC BY 4.0.

← STUPID-2026-0159By ID

Get told when an agent breaks something

We document AI agent failures daily, severity-scored against a published scale. Each Monday, if any scored 7 or above that week — deleted data, leaked secrets, broken production — you get one email with the sources. When nothing did, you get nothing.

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