AEV-2026-0030
Goose ran a shared recipe's stdio extension and retry shell commands before its security scan or any consent gate applied (CVE-2026-85623)
Before a fix ships, Goose recipes can declare a stdio extension command or a retry check shell command that runs the moment the recipe's extensions initialize, independent of whether the MCP handshake that follows ever succeeds. Recipe::check_for_security_warnings inspects only instructions, prompt and activities for hidden Unicode tags, and the CLI recipe run path calls no scan and shows no consent prompt before spawning.
Affected
- Organisation
- unknown
- Product
- Goose CLI
- Component
- Recipe stdio extension initialization (ExtensionConfig::Stdio spawn) and retry.checks / retry.on_failure shell execution
- Versions
- Goose through 1.49.0, the latest released version at the time of this record; no fixed version has shipped
- Configurations
- A shared recipe file, deeplink, GitHub recipe repository or recipe library entry declares an extensions stdio entry with cmd and args, or a retry.checks entry using SuccessCheck::Shell, or a retry.on_failure command
Execution authority facts
Fields the evidence does not establish are shown as unknown rather than guessed.
- Intended task
- Running a shared or imported Goose recipe
- Agent
- Goose CLI (goose run with a recipe)
- Delegating actor
- The developer or user who selected and ran the recipe
- Action
- Spawned an attacker chosen command from the recipe's own stdio extension configuration during extension initialization, and separately executed an attacker chosen shell command from the recipe's retry.checks or retry.on_failure configuration
- Target resource
- The host running Goose, with the invoking user's own privileges
- Environment
- A local developer or user workstation running goose run against a shared recipe file, deeplink or GitHub recipe repository
- Credentials used
- unknown
- Privileges available
- The full privileges of the user account running Goose
- Authority presented
- The user's decision to select and run the recipe
- Authority required
- Authorization for host command execution with the invoking user's own privileges
- Applicable policy
- Recipe::check_for_security_warnings, which inspects only instructions, prompt and activities for hidden Unicode tag content and does not examine extensions.cmd, extensions.args, retry.checks.command or retry.on_failure
- Approval mechanism
- none in the CLI recipe run path
- Required approver
- unknown
- Independent approval
- no
- Action binding
- unknown
- Sequence context
- Runs during recipe extension initialization, before or independent of whether the MCP handshake that follows ever succeeds, and before any security scan or consent prompt in the CLI path
Impact
- Consequence
- material
- Reach
- single
- Reversibility
- unknown
- Detectability
- silent
- Propagation
- potential
- Recovery
- unknown
Evidence
Primary sources
- A shared recipe silently runs arbitrary commands (stdio extension cmd / retry shell checks), and the recipe security scan does not cover those fields (Issue 10325) (GitHub, aaif-goose/goose)
Supporting sources
- fix(recipe): extend security scan to cover stdio extensions and retry shell checks (Pull Request 10337) (GitHub, aaif-goose/goose)
- recipe/mod.rs at v1.49.0 (GitHub, aaif-goose/goose)
- recipe/mod.rs on main (GitHub, aaif-goose/goose)
- agents/extension.rs at v1.49.0 (GitHub, aaif-goose/goose)
- agents/extension_manager.rs at v1.49.0 (GitHub, aaif-goose/goose)
- agents/retry.rs at v1.49.0 (GitHub, aaif-goose/goose)
- goose-cli session/builder.rs on main (GitHub, aaif-goose/goose)
- Releases, aaif-goose/goose (GitHub, aaif-goose/goose)
- Reproduction status
- The primary issue's own reporter demonstrated command execution with a stdio extension that ran a benign command and wrote its output to a file, as the invoking user, with the extension then failing to initialize. Moona Intelligence independently verified the described spawn and scan gap directly against the crates/goose source at the v1.49.0 tag and at the current main branch, rather than by running the recipe itself.
- Evidence state
- Confirmed
Known unknowns
- Whether this has been exploited against a real deployment.
- Whether Goose Desktop's own recipe trust dialog can be reached before or only after a stdio extension or retry command has already executed. This record verifies the CLI path only.
- Whether a fixed release has since shipped after this record's retrieval date.
Limitations
- The GitHub issue and the linked pull request were fetched directly. The CVE Program's own record and a secondary threat intelligence aggregator could not be fetched directly in this session and are corroborated through search rather than a direct read. The CVSS score is stated on that corroborated basis only.
Claim provenance
- verified
The primary issue, fetched directly, states the mechanism in the reporter's own words: extensions spawn via Command::new(cmd).args(args) and then spawn() before any MCP handshake completes and regardless of its outcome, retry.checks executes shell commands via sh -c from recipe configuration, and Recipe::check_for_security_warnings inspects only instructions, prompt and activities, never the extensions or retry fields. Independently confirmed by this record directly against crates/goose/src/agents/extension_manager.rs, crates/goose/src/agents/retry.rs and crates/goose/src/recipe/mod.rs at the v1.49.0 tag and at current main.
The User Chose a Recipe. Goose Treated That as Permission to Run Its Commands. - verified
The proposed remediation, fetched directly, confirms the scope of the gap it was written against (extensions.cmd and extensions.args, retry.checks.command, retry.on_failure, InlinePython code) and that it closed without merging. This record treats it as a proposed and not a shipped fix.
The User Chose a Recipe. Goose Treated That as Permission to Run Its Commands.
