Skip to main content

Module shell_expand

Module shell_expand 

Source
Expand description

Expand a shell command line into the set of commands a shell would run.

Deny rules are the one gate that holds under AskForApproval::Never, so they cannot be matched against the raw command string: the string a user types and the set of commands the shell executes are different things. A command substitution runs its body (`rm -rf /`, $(rm -rf /)), a quoted argument executes with the quotes removed (rm -rf "/"), and a wrapper hands its payload straight back to a shell (bash -c '…', eval '…', sudo …).

Matching one string pattern per metacharacter loses that race by construction — every new quoting or wrapping form is another bypass. This module instead tokenizes the command the way a POSIX shell word-splits it and returns every command line that would actually be executed, so deny rules can be matched against each one.

Deliberately conservative in the deny direction: when a construct is ambiguous the expander emits extra candidate command lines rather than fewer. Over-emitting only makes deny matching stricter — denied_prefix_matches stays anchored at the first positional token, so an extra candidate that no rule names is inert. Under-emitting is a bypass.

What it does not do is evaluate anything: $VAR is left as literal text, and single-quoted text is never treated as code (echo ' + “" + rm -rf /" + "” + ' really does just print). Fidelity to shell semantics is the point in both directions.

Functions§

expanded_commands
Returns every command line the shell would execute for command.