You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Sandbox command evidence redacts credentials inside supported wrapper operands without creating unbounded recursive parsing or masking benign command arguments.
Current defect
Draft #906 contains the direct Docker/Podman login -p, -p=, and --password= repair, but the current command-text path tokenizes only the outer command. Direct reproductions remain:
env -S 'docker login -p <opaque>';
sh -c 'podman login -p <opaque>';
nested env → shell -c combinations.
The opaque credential survives because the wrapper operand is treated as ordinary data. Blindly calling the text and argv redactors recursively would instead create attacker-controlled recursion/CPU risk.
Required repair
recognize only exact wrapper program basenames and exact option/operand positions:
env -S, env --split-string, and the long --split-string=... spelling;
sh, bash, dash, ksh, or zsh command strings selected by an exact/combined -c option;
preserve the public APIs through private depth/context helpers and compile the literal matcher once at the public entry point;
use MAX_COMMAND_WRAPPER_DEPTH = 4, MAX_COMMAND_INPUT_BYTES = 65_536, MAX_COMMAND_TOKENS = 4_096, and MAX_COMMAND_WORK = 262_144; share one UTF-8 byte/token/cumulative-work budget across the complete wrapper tree;
at the depth bound, redact the entire remaining nested operand; at a root byte/token/work limit, fail closed for the complete public evidence;
fail closed on malformed quoting/tokenization without publishing the raw nested operand or parser diagnostic;
preserve benign env -u/--unset, env -C/--chdir, assignments, Docker publish-port -p 8080:80, and SSH port -p 22 diagnostics;
keep the direct Docker/Podman fix and its runtime-synthesized fixtures.
Security design constraints
Python shlex is not a semantic parser for either full shell -c input or GNU env -S; it may be used only after a linear quote-state scanner accepts a documented grammar subset.
For every supported wrapper, backslashes, line breaks, an unquoted $, backtick, or #, and unclosed/unsupported quoting fail closed. For shell operands, unquoted control/operators such as ;, &&, ||, pipes, redirection, substitution, heredoc, parentheses, and glob/meta syntax also fail closed. Expansion inside double quotes is unsupported and fails closed.
GNU env -S / --split-string has its own escape, comment, expansion, and trailing-argv behavior. Unsupported #, backslash forms (including \c), ${...}, or any trailing argv that could combine with the split operand fail closed for the complete command evidence.
Shell -c following $0/positional argv must be preserved only under an explicitly proven mapping; otherwise the complete command evidence fails closed. A compound command such as sh -c 'echo ok; docker login -p <opaque>' must never be treated as one simple shlex command.
Share one precompiled sensitive-value context and the single cumulative budget across every nested wrapper. Depth-only recursion, repeated full rescans, and repeated unbounded shlex.join expansion are forbidden.
Malformed syntax, unsupported grammar, depth exhaustion, or budget exhaustion returns bounded redaction without raw text or exception details.
Container-login detection is exact: the normalized program is Docker/Podman and command[1] == "login"; never infer the subcommand using membership elsewhere in argv.
Fix and pin the current option false positives:
docker login --password-stdin registry preserves the registry because the option consumes stdin, not the following argv element;
--password-stdin=... remains conservatively redacted because it is not the valid no-argument form;
docker run --name login -p 8080:80 image and docker run login -p 8080:80 image preserve the publish port because an unrelated login argument is not the login subcommand.
fail-first tests cover env -S, env --split-string, long = form, every listed shell basename and combined -c selector, env → shell nesting, malformed inner/outer quoting, compound shell syntax, env escapes/expansion/trailing argv, and a fixed ten-level nesting tree;
boundary tests cover input UTF-8 bytes, total parsed tokens, cumulative scan work, maximum depth, and each limit plus one;
negative tests prove benign env options/assignments, --password-stdin registry, unrelated login arguments, Docker publish ports, and SSH ports are byte-visible;
direct Docker/Podman -p, -p=, and --password= credential cases remain redacted;
all credential-shaped fixtures are synthesized at runtime; no fixed credential-shaped literal is committed;
Sandbox Log Redaction Quality CI passes at the exact head with 100% statement/branch coverage for the three owned production modules;
full suite, compile/docstring checks, Secret Scan over the full PR range, security/supply-chain gates, current source review, independent non-author approval, and protected-main stdout/stderr/timeout/service-tail canaries pass;
Outcome
Sandbox command evidence redacts credentials inside supported wrapper operands without creating unbounded recursive parsing or masking benign command arguments.
Current defect
Draft #906 contains the direct Docker/Podman
login -p,-p=, and--password=repair, but the current command-text path tokenizes only the outer command. Direct reproductions remain:env -S 'docker login -p <opaque>';sh -c 'podman login -p <opaque>';env→ shell-ccombinations.The opaque credential survives because the wrapper operand is treated as ordinary data. Blindly calling the text and argv redactors recursively would instead create attacker-controlled recursion/CPU risk.
Required repair
env -S,env --split-string, and the long--split-string=...spelling;sh,bash,dash,ksh, orzshcommand strings selected by an exact/combined-coption;MAX_COMMAND_WRAPPER_DEPTH = 4,MAX_COMMAND_INPUT_BYTES = 65_536,MAX_COMMAND_TOKENS = 4_096, andMAX_COMMAND_WORK = 262_144; share one UTF-8 byte/token/cumulative-work budget across the complete wrapper tree;shell=False, environment, exit, timeout, process-group, and cleanup behavior;env -u/--unset,env -C/--chdir, assignments, Docker publish-port-p 8080:80, and SSH port-p 22diagnostics;Security design constraints
shlexis not a semantic parser for either full shell-cinput or GNUenv -S; it may be used only after a linear quote-state scanner accepts a documented grammar subset.$, backtick, or#, and unclosed/unsupported quoting fail closed. For shell operands, unquoted control/operators such as;,&&,||, pipes, redirection, substitution, heredoc, parentheses, and glob/meta syntax also fail closed. Expansion inside double quotes is unsupported and fails closed.env -S/--split-stringhas its own escape, comment, expansion, and trailing-argv behavior. Unsupported#, backslash forms (including\c),${...}, or any trailing argv that could combine with the split operand fail closed for the complete command evidence.-cfollowing$0/positional argv must be preserved only under an explicitly proven mapping; otherwise the complete command evidence fails closed. A compound command such assh -c 'echo ok; docker login -p <opaque>'must never be treated as one simpleshlexcommand.shlex.joinexpansion are forbidden.command[1] == "login"; never infer the subcommand using membership elsewhere in argv.docker login --password-stdin registrypreserves the registry because the option consumes stdin, not the following argv element;--password-stdin=...remains conservatively redacted because it is not the valid no-argument form;docker run --name login -p 8080:80 imageanddocker run login -p 8080:80 imagepreserve the publish port because an unrelatedloginargument is not the login subcommand.env -u/--unset/-C/--chdirvalues, ordinary assignments, Docker publish ports, and SSH ports.Acceptance
env -S,env --split-string, long=form, every listed shell basename and combined-cselector, env → shell nesting, malformed inner/outer quoting, compound shell syntax, env escapes/expansion/trailing argv, and a fixed ten-level nesting tree;--password-stdinregistry, unrelatedloginarguments, Docker publish ports, and SSH ports are byte-visible;-p,-p=, and--password=credential cases remain redacted;Related: #906, #908, #766.