framework: make tool discoverability, workspace placement and model tiering mechanical #1174
@@ -282,6 +282,18 @@ FIXTURES="$TMP/fixtures.tsv"
|
||||
printf '2\t{"tool_input":{"command":"curl -K/tmp/provider-write.cfg"}}\tcurl accepts the value attached to the short flag\t--config/-K\n'
|
||||
printf '2\t{"tool_input":{"command":"curl -sK /tmp/provider-write.cfg"}}\tand inside a bundle, which a space-separated test does not see\t--config/-K\n'
|
||||
printf '0\t{"tool_input":{"command":"tar -K /tmp/archive.tar"}}\t-K on a command that is not curl is not this hook'"'"'s business\n'
|
||||
# curl by any ordinary path spelling. The first version of the config check
|
||||
# matched the bare word only, so these three executed the same wrapped write
|
||||
# while the guard reported clean. Recognizing only the unqualified name is
|
||||
# caller-name parsing, and that is the class this file exists to refuse.
|
||||
printf '2\t{"tool_input":{"command":"/usr/bin/curl --config /tmp/provider-write.cfg"}}\tan absolute path is the same invocation, not a different one\t--config/-K\n'
|
||||
printf '2\t{"tool_input":{"command":"env /usr/bin/curl -K/tmp/provider-write.cfg"}}\tand it is still curl behind env, with the value attached\t--config/-K\n'
|
||||
printf '2\t{"tool_input":{"command":"./curl --config /tmp/provider-write.cfg"}}\ta relative path costs two characters and used to be enough\t--config/-K\n'
|
||||
# The prefix must end at a slash: a basename that merely ENDS in curl is a
|
||||
# different program, and blocking it would be the over-block that gets a guard
|
||||
# routed around rather than fixed.
|
||||
printf '0\t{"tool_input":{"command":"mycurl --config /tmp/provider-write.cfg"}}\tmycurl is not curl, and over-blocking is its own failure\n'
|
||||
printf '0\t{"tool_input":{"command":"/opt/x/curl-wrapper --config /tmp/provider-write.cfg"}}\tnor is curl-wrapper, whose name only starts the same way\n'
|
||||
|
||||
# Percent-encoded endpoints. Not hypothetical: /issues/1174 and /iss%%75es/1174
|
||||
# both returned HTTP 200 with the same object from the live forge, so the
|
||||
|
||||
@@ -290,7 +290,18 @@ fi
|
||||
# guard that recognizes only the space- and equals-separated forms is defeated by
|
||||
# deleting one character. Scoped to curl so that `eslint --config .eslintrc.json`
|
||||
# and every other tool with a --config flag are untouched.
|
||||
if printf '%s' "$CMD" | grep -Eq '(^|[[:space:]|;&(])curl([[:space:]]|$)' \
|
||||
#
|
||||
# curl is matched as a BASENAME, not as a bare word: `/usr/bin/curl`, `./curl`
|
||||
# and `env /usr/bin/curl` are ordinary spellings of the same invocation, and the
|
||||
# first version of this check saw none of them. Recognizing only the unqualified
|
||||
# name is caller-name parsing, which is the failure class this file removed
|
||||
# elsewhere and which came straight back in with this control.
|
||||
#
|
||||
# A wrapper script that execs curl on the operator's behalf is still invisible
|
||||
# here, because neither the name nor the request appears in the command text.
|
||||
# That is a real limit of inspecting a command string rather than a defect this
|
||||
# regex can close, and it is stated rather than left for the next reader to find.
|
||||
if printf '%s' "$CMD" | grep -Eq '(^|[[:space:]|;&(])([^[:space:]|;&()]*/)?curl([[:space:]]|$)' \
|
||||
&& printf '%s' "$CMD" | grep -Eq -- '(^|[[:space:]])(-[A-Za-z]*K([[:space:]=]|$|[^[:space:]])|--config([[:space:]=]|$))'; then
|
||||
cat <<EOF
|
||||
BLOCKED: curl invocation whose request is supplied from a --config/-K file.
|
||||
|
||||
Reference in New Issue
Block a user