You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SHELL_EXPANSION_RE gates backticks, $(, and ${, but not a bare $var. Since the destructive and network scans match on literal command names, a name assembled at runtime slips past them:
c=cu'rl';$c example.com # NETWORK_RE never sees "curl"
f='-rf'; rm $f /some/path # DESTRUCTIVE_RE never sees "rm -rf"
This is the POSIX twin of the PowerShell bypass fixed in #37 ($c='Invoke-WebRequest'; & $c example.com). It predates that PR — it's in main today — and the same reasoning applies: keyword scanning is only sound when the command text is literal, and a bare variable breaks that precondition.
The PowerShell gate was scoped to hosts where PowerShell is the interpreter precisely to avoid changing POSIX behavior in a contributor PR. Extending it to POSIX means echo $HOME starts requiring the shell_expansion permission in safe mode, which is a much more visible change — plenty of ordinary commands use variables.
Gate only where it matters — a $ in command-name position (start of a segment, or after the call operator) rather than in argument position. Narrower blast radius, but "command position" needs a real parser to determine reliably, which is its own project (Codex uses tree-sitter for exactly this).
Option 3 is the honest current state and argues for prioritizing sandbox/egress work over more scanner hardening. Worth deciding explicitly rather than leaving the gap undocumented.
Problem
SHELL_EXPANSION_REgates backticks,$(, and${, but not a bare$var. Since the destructive and network scans match on literal command names, a name assembled at runtime slips past them:This is the POSIX twin of the PowerShell bypass fixed in #37 (
$c='Invoke-WebRequest'; & $c example.com). It predates that PR — it's inmaintoday — and the same reasoning applies: keyword scanning is only sound when the command text is literal, and a bare variable breaks that precondition.Why it wasn't fixed alongside #37
The PowerShell gate was scoped to hosts where PowerShell is the interpreter precisely to avoid changing POSIX behavior in a contributor PR. Extending it to POSIX means
echo $HOMEstarts requiring theshell_expansionpermission insafemode, which is a much more visible change — plenty of ordinary commands use variables.Options
$on POSIX too, consistent with Windows: execute string commands with PowerShell 7 #37. Most sound, most disruptive; needs a look at how often realsafe-mode usage would start prompting.$in command-name position (start of a segment, or after the call operator) rather than in argument position. Narrower blast radius, but "command position" needs a real parser to determine reliably, which is its own project (Codex uses tree-sitter for exactly this).Option 3 is the honest current state and argues for prioritizing sandbox/egress work over more scanner hardening. Worth deciding explicitly rather than leaving the gap undocumented.
Related: #37, #43.