- Model bash brace expansion (comma lists) before the block and read scans, so a payload such
as {touch,/tmp/x} or {python3,-c} '...' is seen as the writer / interpreter bash actually
runs. Only unquoted groups with a top-level comma expand; {} (find -exec), ${VAR} parameter
expansion, numeric {1..5} sequences and quoted braces are left intact, and expansion is
bounded.
- Resolve the reader / command word in the shell-string sensitive-read scan past leading
VAR=value assignments and command wrappers (env / nice / timeout / ...), flag a VAR=value
whose value is a sensitive path, and recursively scan a nested bash -c '<payload>' shell, so
a read hidden behind a normal command-prefix form is caught. The classifier and terminal
scanners now share one _scan_command_string_for_reads with a strict_traversal knob (strict
for os.system shell strings, lenient .. for benign in-tree terminal navigation).
- Treat unbound MRO / getattribute access on a guarded file class as the same recovery gadget
as io.FileIO.__mro__: type.mro(io.FileIO), type.__getattribute__(io.FileIO, '__mro__') /
object.__getattribute__(..., 'mro'), and getattr(io.FileIO, '__mro__') are blocked.
Adds TestRound25Bypasses plus terminal brace / prefixed-read regression tests.