2 Commits

Author SHA1 Message Date
lihongyuan99
8c2f066159
fix(skills): read one shell vocabulary in the curl-pipe-shell rule (#7378)
`shell-curl-pipe-shell` hard-codes `bash|zsh|dash|fish|sh` in the download-pipe
matcher while the structural `env` fallback reads `_SHELL_NAMES`. The two lists
drift: `curl ... | ksh` (and csh/tcsh/ash/mksh) pipes a fetched script in
silence, even though sandbox_audit_middleware already treats ksh as a shell.

Derive the alternation from `_SHELL_NAMES` and widen both to the same ten
names, so a shell added once is visible to both detectors.
2026-10-24 08:03:36 +08:00
sxh
53df22bdd2
fix(skillscan): catch a shell behind a sudo option that takes a value (#6372)
* fix(skillscan): catch a shell behind a sudo option that takes a value

`shell-curl-pipe-shell` skips a leading `sudo` and its standalone flags, but
`| sudo -u deploy bash` left the matcher parked on the option value, so a
remote script piped into a shell went unreported. Let a value-taking sudo
option consume its value as well.

* fix(skillscan): keep the sudo option branches mutually exclusive

A chain of value-taking options (`curl ... | sudo -u -u -u ... cat`) matched both sudo alternatives inside the lazy repeat, so re.search explored every one-/two-token partition before the non-shell tail failed: a 211-byte input took exponential time and did not return. Excluding value-taking options from the standalone branch lets each token be consumed exactly one way, so a failing chain stays linear while `sudo -u deploy bash` and `sudo -E bash` still report.

* fix(skillscan): treat `sudo -h` as taking a value in the download pipe

The hand-maintained class of sudo options that take a separate value
missed `-h host` (the deprecated remote-host option), so
`curl … | sudo -h host bash` parked the matcher on the host name and
produced no finding — the same miss shape this class exists to prevent.
Add `h`, note that the class is hand-maintained, and pin every letter of
it with a contract test so a dropped letter fails instead of regressing
to a silent miss.

Also build the repeated-option payload in the linearity regression from
the module constant rather than a second inline copy, so the byte-count
pin and the subprocess exercise the same string.

---------

Co-authored-by: sxh313 <sxh313@users.noreply.github.com>
2026-10-06 21:18:53 +08:00