Development record
`.abcd/development/brief/04-surfaces/17-guard.md:1044`: The chapter lists same-line carried values as unseen and calls the matter an open ruling, but they block and the ruling is made. All block when the value is assigned on the line (`X='rm -rf /'; eval "$X"`, `P=pkill; $P make`). The ruling is made: internal/core/guard/carried.go cites it, and iss-2609281134544802 is in .abcd/work/issues/resolved/.
issueopenminoriss-2611060810026397
.abcd/development/brief/04-surfaces/17-guard.md:1044: The chapter lists same-line carried values as unseen and calls the matter an open ruling, but they block and the ruling is made. All block when the value is assigned on the line (X='rm -rf /'; eval "$X", P=pkill; $P make). The ruling is made: internal/core/guard/carried.go cites it, and iss-2609281134544802 is in .abcd/work/issues/resolved/.
Frontmatter
| id | iss-2611060810026397 |
|---|---|
| type | issue |
| lifecycle | open |
| severity | minor |
.abcd/work/issues/open/iss-2611060810026397-abcd-development-brief-04-surfaces.md
open on GitHub ↗ · commit history ↗
mentions1
- iss-2609281134544802The shell guard reads a parameter expansion as an unknown word (iss-2609251824244354, lane drainG3) for the flags and program names its value can spell, but not as data an earlier command carried into the variable, and four classes stay unread: (1) a pid list a search printed into a variable (p=$(pgrep make); kill $p, or pgrep make | while read p; do kill $p; done), the plain-variable half [dcn-2609250000000016](../../decisions/dcn-2609250000000016-correction-to-the-two-entries-above-on.md) (c) parked on iss-2609251824244354; (2) a stream path in a variable handed to a shell or source as its script (bash "$f" after f=<(curl ...)); (3) shell text a variable holds, run through eval "$X", sh -c "$X", or placed in a string a shell runs, whose value may hold a separator or quotes (eval "$X" allows, as it did before the reading); (4) pkill or killall as a variable's value standing as the program with an operand ($P make), and a variable-named bare interpreter inside a string. Reading each would refuse ordinary commands: the false-positive sweep of 4,315 inputs showed 22 new program-name-unknown blocks ("$GO" build, exec "$BIN", $EDITOR notes.md) and 15 new interpreter-reads-stream blocks (bash "$SCRIPT") before these readings were left out. Classes 1 and 3 carry the same cost, from the sweep's everyday-variable lines, each of which allows today: a reading of class 1 cannot tell a pid a search printed from one the script recorded, so it would refuse kill "$pid", kill -TERM "$PID" and kill -- -"$pg" (a background job's pid, a pidfile's, a process group's); a reading of class 3 cannot tell a hostile string from a composed one, so it would refuse eval "$cmd", the line that runs a command a script built up. Each class is a block, warn or allow call the product thinker has not ruled on.