// threat brief
Roo Code auto-approve bypass: the ${ command; } form lets denied shell commands slip past the check
- CVSS
- 7.7 HIGH
- CISA KEV
- Not listed
- Weakness
- CWE-436
- Topics
- AI security
AI review 2026-10-18 (not human-reviewed)Command tests: none yetReproduced: not yetVerification record ↓
Roo Code ≤3.54.0 misreads ${ cmd; } syntax; with auto-approve on and bash 5.3+/ksh93, prompt-injected agents can run denied commands unapproved. No known fix.
| Who is affected | People using Roo Code 3.54.0 or earlier with auto-approve for command execution turned on (the CVE record's title says Auto-Approve; the setting name "always approve execute" comes from the researcher's write-up). Per the CVE record, two more things must also hold - the agent reads attacker-controlled content (indirect prompt injection), and the allowlist contains an outer command, such as echo, that the denied command can be wrapped in. The hidden command only actually runs if the shell is bash 5.3 or later, or ksh93. |
|---|---|
| What happens | If the AI agent reads a file, web page, repository or MCP result containing malicious instructions, it may propose a harmless-looking command that hides a command you put on your denylist. That command then runs with the agent's auto-execute privileges, without asking you. |
| What to do now | No fixed version is known and the project is archived. Our analysis: turning off "always approve execute" would likely avoid the automatic execution; longer term, consider moving to a tool that is still maintained. |
| Affected versions | All versions through 3.54.0 (the researcher tested main-branch commit b867ec9, which the researcher labels v3.53.0; per the repository history, that commit comes after the v3.54.0 release) |
| Fixed versions | No known fixed version; the project is archived and v3.54.0 is the last extension release |
| CVSS vector | Show full vectorCVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N |
| Timeline |
|
Blue team playbook
Check, fix / mitigate, respond, harden. Matching the affected versions does not mean you were compromised, and a check that finds nothing does not prove you are safe; each item says what it can and cannot show. Tagged steps point to where the attack flow below can be stopped.
- 01Check whether you use Roo Code 3.54.0 or earlier
Where to run it: in a terminal (bash or zsh) on the computer where VS Code is installed; it only lists the extensions and versions installed in that computer's VS Code. Everything through 3.54.0 is affected. The releases page lists v3.54.0 as the latest extension release, so our analysis is that any installed version is likely in the affected range. Whether you are actually exposed depends on the auto-approve setting and your shell. Limitation: this only works with VS Code's `code` CLI; if you use Roo Code in another VS Code-compatible editor, this command won't find it, so use that editor's own CLI or extensions view instead.
Read-only checkcode --list-extensions --show-versions | grep -i roo - 02Check the auto-approve setting and your shell version
The hidden command only runs automatically if "always approve execute" is on and the agent's shell is bash 5.3+ or ksh93. Where to run it: in VS Code's integrated terminal on the computer where Roo Code actually runs commands; it only reads a version and changes nothing. Limitation: this shows the bash found on your PATH, which isn't necessarily the shell the agent uses; it can't detect ksh93 and can't check the auto-approve setting. Roo Code's documentation labels "Use Inline Terminal" as recommended; two places in the source code set its default differently, so we can't confirm whether it is on by default. Per the documentation, when it is on it runs commands through a background execa provider, bypassing shell profiles and VS Code shell integration, and the documentation doesn't say which shell is used then. Only with Inline Terminal turned off does Roo Code use VS Code's integrated terminal and your shell profile (you can see the default profile with "Terminal: Select Default Profile" in the Command Palette). So the shell the agent actually uses needs to be confirmed separately, not just from the default profile; whether auto-approve is on has to be checked in Roo Code's auto-approve settings.
Read-only checkbash --version | head -n 1 - 03Review the terminal commands the agent ran
Our suggestion: look back at commands the agent auto-ran, watching for allowlisted commands that contain a ${ construct wrapping another command. The sources give no detection guidance.
- 01Turn off "always approve execute"
This is our analysis, not vendor guidance: the bypass needs auto-approve, and with it off every command asks you first.
- 02Don't combine auto-approve with bash 5.3+ or ksh93
Our analysis: the researcher says shells without this syntax won't run the hidden command, but the parser flaw remains, so this lowers risk rather than fixing it.
- 01Assume anything the agent could reach may have been touched
Our suggestion: if you find a denied command ran, review the files and credentials within the agent's reach and rotate credentials where needed. The sources give no incident-response guidance.
- 01Move to a tool that is still maintained
The product was tagged unsupported when the CVE was assigned and the project is archived; we think a fixed release is unlikely.
- 02Don't treat allow and deny lists as your only defense
Our suggestion: lists depend on the parser understanding shell syntax correctly and fail when it doesn't; pair them with least privilege and isolated environments.
Full remediation steps and notes
No source names a fixed version, fix commit or vendor advisory. The vendor’s releases page shows v3.54.0 as the last extension release and the repository is archived, so our analysis is that a fixed release is unlikely. Everything below is our analysis, not vendor guidance:
- Check your shell first. On the computer where Roo Code runs commands, open VS Code’s integrated terminal and run
bash --version(this only shows the bash on your PATH. Roo Code’s documentation labels “Use Inline Terminal” as recommended; two places in the source code set its default differently, so we can’t confirm whether it is on by default. Per the documentation, with it on Roo Code runs commands through a background execa provider that bypasses shell profiles, and the documentation doesn’t say which shell it uses then; only with Inline Terminal off does it use VS Code’s integrated terminal default profile. Confirm separately which shell the agent actually uses; a zsh default profile doesn’t by itself mean the command won’t run); if it’s 5.3 or later, or the agent uses ksh93, and auto-approve is on, you’re in the scenario where the command actually runs. - Turning off auto-approve is the most direct step. The bypass needs “always approve execute”; with it off, every command needs your approval. Switching to zsh or an older bash only stops the command from running; the parser flaw remains, so it isn’t a fix.
- Plan a migration. The product is unsupported; longer term, move to a tool that is still maintained.
Attack flow
Read left to right: this is the order the attack happens in. A blue shield means the step can be stopped; the earlier, the better. Click an icon for details.
Read top to bottom: this is the order the attack happens in. A blue shield means the step can be stopped; the earlier, the better. Tap an icon for details.
- Attacker
Plants malicious instructions in content the agent will read
This is called indirect prompt injection: the attacker doesn't touch your machine, they just put instructions into a file, web page, repository or MCP result the agent will read.
Defense: Don't let an agent with auto-execute enabled work on untrusted content.
- Your system
The agent proposes an allowlisted command with a denied command hidden inside
The outer command is something on the allowlist, such as echo, and the denied command is wrapped in the ${ ...; } form.
- Your system
parseCommandLine() treats it as a harmless parameter expansion and never checks the inner command
The parser swaps every ${...} for a placeholder with a single rule, so the command inside is never compared to the allow and deny lists.
Defense: Our analysis: turn off "always approve execute" so every command needs your approval.
- Your system
The command is auto-approved and the shell runs the hidden command
Only bash 5.3+ or ksh93 run it, with the agent's auto-execute privileges. The researcher notes zsh and bash 5.2 or earlier do not run it, though the parser flaw is still there.
Defense: Run the agent in a least-privilege environment that limits the files and credentials it can reach.
Who is affected
| Condition | Affected? |
|---|---|
| Roo Code through 3.54.0 + auto-approve on (called “always approve execute” in the researcher’s write-up) + shell is bash 5.3+ or ksh93 + an outer command such as echo on the allowlist that can wrap the denied command + the agent reads attacker-controlled content (indirect prompt injection) | Affected; denied commands can run automatically without approval (per the CVE record) |
| Roo Code through 3.54.0 + auto-approve on + shell is zsh or bash 5.2 or earlier | The researcher says the command doesn’t run, but the parser flaw is still present |
| Roo Code through 3.54.0 + auto-approve off | Commands ask you first; our analysis is they won’t run automatically |
| A fixed version | No source mentions one |
“The researcher’s write-up” on this page is the vulnerability write-up the finders, Minqiang Gui and Siyu Lou, published on GitHub (listed as the Researcher Disclosure in the CVE record); that page contains exploit code, so we don’t link to it. The researcher tested main-branch commit b867ec9 and labels it v3.53.0; however, per the repository history, b867ec9 is not the v3.53.0 release commit but a May 15, 2026 commit that comes two commits after the v3.54.0 release commit (f49f0ce). VulnCheck, which assigned the CVE, tagged it unsupported-when-assigned, meaning the product was no longer supported when the CVE ID was assigned. The vendor’s GitHub repository is archived (read-only), and sources disagree on the date: the repository banner says May 15, 2026, while the researcher’s write-up quotes May 16. A third-party news tracker also reports that the whole Roo Code suite (Extension, Cloud and Router) shut down on May 15, 2026.
How it works
Roo Code is an AI coding assistant (an “agent”) that can run shell commands in your terminal. With auto-approve on (the researcher’s write-up calls the setting “always approve execute”, and this page uses that name; the CVE record only says auto-approve), it stops asking you and instead checks each command against an allowlist and a denylist to decide on its own.
To do that check, it first has to split the command line apart and find every command that will actually run. That’s the job of parseCommandLine(). The problem is how it handles ${...}:
- In older shells, forms like
${NAME}are “parameter expansions”: they just read a variable’s value and run nothing. - bash 5.3 (2025) added a
${ command; }form (called funsub command substitution), which does run the command inside.
Roo Code’s parser uses one regular expression to treat every ${...} as a parameter expansion and hide it behind a placeholder, so the command inside is never compared to the lists. All that’s left is an outer command on the allowlist, such as echo, which gets auto-approved. The parser and the shell read the same text differently, which is what CWE-436 (Interpretation Conflict) describes.
The realistic trigger usually isn’t the user but indirect prompt injection: a file, web page, repository or MCP result the agent reads contains instructions that steer it into proposing such a command. The command runs with the agent’s auto-execute privileges.
The flawed approach (conceptual illustration, not the original source code):
Show code example(ts)
// Treat every ${...} as "just a variable" and hide it behind a placeholder
cmd = cmd.replace(/\$\{[^}]+\}/g, () => PLACEHOLDER)
// Then only the outer command is checked → it's on the allowlist → auto-approvedThe approach the researcher recommends (per the researcher’s write-up, which contains exploit code, so we don’t link to it; conceptual illustration, not a vendor fix):
Show code example(ts)
// The ${ ...; } funsub form is not a parameter expansion:
// pull out the inner command and check it against the lists like any other substitution
if (isFunsub(segment)) {
checkAgainstLists(innerCommand(segment))
}Timeline
| Date | Event |
|---|---|
| 2025 (per the researcher’s write-up) | bash 5.3 adds the ${ command; } form; the bash release notes confirm the new syntax |
| 2026-05-15 | A third-party news tracker reports the Roo Code suite shut down |
| 2026-05-15 or 05-16 | Repository archived (the banner says the 15th; the researcher’s write-up quotes the 16th) |
| 2026-10-13 | CVE published; NVD entry published; GitHub advisory GHSA-mfc9-vhw7-f5w9 published (not reviewed by GitHub) |
| 2026-10-14 | Not listed in CISA KEV as of this date |
| 2026-10-15 | NVD finished its analysis (status “Analyzed”) but gave no score of its own; it only lists the scores from VulnCheck, the assigner |
Further reading
- Scoring: NVD finished its analysis on 2026-10-15 but gave no score of its own; it only lists the scores from VulnCheck, the assigner (CVSS 4.0 7.7, CVSS 3.1 8.8). The CVE record lists CVSS 3.1 8.8 (supplied by VulnCheck, the assigner) and CVSS 4.0 7.7; this page uses the 4.0 score. Both say the attacker needs no privileges; 3.1 says user interaction is required, while 4.0 rates it as passive.
- Exploitation: CISA’s SSVC rating marks it
poc, meaning a public proof of concept exists. That does not mean it has been exploited in the wild. No source reports in-the-wild or zero-day exploitation. - Credited to Minqiang Gui and Siyu Lou. Their write-up contains exploit code, so we don’t link to it; see the CVE record, NVD and the VulnCheck advisory for the vulnerability details.
- Related: CVE-2026-63108 is a separate Roo Code (≤3.54.0) auto-approve bypass that also involves how the parser handles parameter expansions, but it is a different CVE.
- Related weakness type: CWE-436.
Verification Checked item by item against sources by AI under our review rules, all passed; not human-reviewed and not yet reproduced in our lab
| AI review | 2026-10-18 · review rules |
|---|
Verification records describe the environment and the result only, never reproduction steps or code that could attack other people’s systems. See our policy.
Sources
- CVE / NVD / OSVCVE-2026-110204 Record (CVE API) · CVE Program / VulnCheck (CNA), 2026-10-13 · accessed 2026-10-14
- CVE / NVD / OSVNVD - CVE-2026-110204 · NIST, 2026-10-13 · accessed 2026-10-14
- AdvisoryRoo Code through 3.54.0 Auto-Approve Bypass via Funsub Command Substitution · VulnCheck · accessed 2026-10-14
- AdvisoryGitHub Advisory Database: GHSA-mfc9-vhw7-f5w9 · GitHub, 2026-10-13 · accessed 2026-10-14
- VendorRoo-Code v3.54.0 src/shared/parse-command.ts · RooCodeInc (GitHub) · accessed 2026-10-14
- VendorRoo-Code releases · RooCodeInc (GitHub) · accessed 2026-10-14
- VendorRoo Code docs - Shell Integration (Use Inline Terminal) · RooCodeInc · accessed 2026-10-14
- VendorGitHub compare: Roo-Code v3.54.0...b867ec9 · GitHub · accessed 2026-10-14
- OtherBash NEWS (bash 5.3 changes) · Chet Ramey / Case Western Reserve University · accessed 2026-10-14
- NewsRoomote / Roo Code sunset · Distill Intelligence · accessed 2026-10-14
- AdvisoryRoo Code command injection via parameter expansion parsing (CVE-2026-63108) · VulnCheck · accessed 2026-10-14
Press brief
In one sentence
Roo Code is an AI coding assistant that can run shell commands for developers automatically. The parser it uses to decide whether a command is allowed mistakes the ${ command; } form added in bash 5.3 for harmless content, so, when the "always approve execute" setting is on and the shell is bash 5.3+ or ksh93, denied commands that a prompt-injected agent proposes can run without the user's approval. The CVE went public on October 13, 2026, and affects versions through 3.54.0; the project was archived in May 2026 and no fix is known. As of October 14 it is not on CISA's Known Exploited Vulnerabilities catalog.
Key facts
- Severity
- CVSS 4.0 7.7; CVSS 3.1 8.8 (VulnCheck) cveawg.mitre.org
- Affected versions
- Through 3.54.0 cveawg.mitre.org
- Disclosed
- 2026-10-13 cveawg.mitre.org
- GitHub advisory ID
- GHSA-mfc9-vhw7-f5w9 (not reviewed by GitHub) api.github.com
- Credited to
- Minqiang Gui, Siyu Lou vulncheck.com
Confirmed
- In Roo Code through 3.54.0, parseCommandLine() treats ${ command; } as a parameter expansion, so the command inside is never checked.
- With 'always approve execute' on, denied commands hidden inside an allowlisted command can run without user approval on bash 5.3+ or ksh93.
- CISA's SSVC rating marks a public proof of concept (poc); as of 2026-10-14 it is not in KEV.
Unconfirmed / disputed
- The archive date differs: the repository banner says 2026-05-15, while the researcher's write-up quotes 2026-05-16.
- No source names a fixed version, fix commit or vendor advisory.
- No source reports exploitation in the wild, or exploitation as a zero-day.
Quotable line
A denylist only blocks the commands it can read; the shell learned a new trick, and the gatekeeper never did.
Images
Download the share image (PNG) · Attack flow diagram (downloadable)
Please credit "PlainCVE" and link to this page. Full citation format is under "How to cite" below. Found a factual error? Report it.
Roo Code auto-approve bypass: the ${ command; } form lets denied shell commands slip past the check
Roo Code is an AI coding assistant that can run shell commands for developers automatically. The parser it uses to decide whether a command is allowed mistakes the ${ command; } form added in bash 5.3 for harmless content, so, when the "always approve execute" setting is on and the shell is bash 5.3+ or ksh93, denied commands that a prompt-injected agent proposes can run without the user's approval. The CVE went public on October 13, 2026, and affects versions through 3.54.0; the project was archived in May 2026 and no fix is known. As of October 14 it is not on CISA's Known Exploited Vulnerabilities catalog.
Key facts:
- Severity:CVSS 4.0 7.7; CVSS 3.1 8.8 (VulnCheck)(https://cveawg.mitre.org/api/cve/CVE-2026-110204)
- Affected versions:Through 3.54.0(https://cveawg.mitre.org/api/cve/CVE-2026-110204)
- Disclosed:2026-10-13(https://cveawg.mitre.org/api/cve/CVE-2026-110204)
- GitHub advisory ID:GHSA-mfc9-vhw7-f5w9 (not reviewed by GitHub)(https://api.github.com/advisories?cve_id=CVE-2026-110204)
- Credited to:Minqiang Gui, Siyu Lou(https://www.vulncheck.com/advisories/roo-code-through-3.54.0-auto-approve-bypass-via-funsub-command-substitution)
Confirmed:
- In Roo Code through 3.54.0, parseCommandLine() treats ${ command; } as a parameter expansion, so the command inside is never checked.
- With 'always approve execute' on, denied commands hidden inside an allowlisted command can run without user approval on bash 5.3+ or ksh93.
- CISA's SSVC rating marks a public proof of concept (poc); as of 2026-10-14 it is not in KEV.
Unconfirmed / disputed:
- The archive date differs: the repository banner says 2026-05-15, while the researcher's write-up quotes 2026-05-16.
- No source names a fixed version, fix commit or vendor advisory.
- No source reports exploitation in the wild, or exploitation as a zero-day.
「A denylist only blocks the commands it can read; the shell learned a new trick, and the gatekeeper never did.」— PlainCVE
https://plaincve.date/en/vulns/cve-2026-110204-roo-code-funsub-approval-bypassHow to cite this page
This article is CC BY 4.0. Please keep the attribution and link when republishing.
PlainCVE Team (2026). "Roo Code auto-approve bypass: the ${ command; } form lets denied shell commands slip past the check". PlainCVE. https://plaincve.date/en/vulns/cve-2026-110204-roo-code-funsub-approval-bypass (accessed YYYY-MM-DD)BibTeX
@misc{cve2026110204roocodefunsubapprovalbypass2026,
title = {Roo Code auto-approve bypass: the ${ command; } form lets denied shell commands slip past the check},
author = {PlainCVE Team},
year = {2026},
howpublished = {PlainCVE},
url = {https://plaincve.date/en/vulns/cve-2026-110204-roo-code-funsub-approval-bypass},
note = {Updated 2026-10-18}
}