Skip to content

.#13476

Closed
teknium1 wants to merge 1 commit intomainfrom
sec/approval-shell-bypass
Closed

.#13476
teknium1 wants to merge 1 commit intomainfrom
sec/approval-shell-bypass

Conversation

@teknium1
Copy link
Copy Markdown
Contributor

@teknium1 teknium1 commented Apr 21, 2026

No description provided.

…mmand detection

DANGEROUS_PATTERNS ran against the literal command string, so four shell
tokenization tricks that the shell strips or substitutes at exec time would
silently bypass every detection rule. Reported in GHSA-xvmp-c27r-qw3c and
GHSA-pwx6-3q74-cxwr.

Bypasses closed:
1. Empty quote pairs: `r""m -rf /tmp` → shell collapses `r""m` to `rm`
2. ${IFS} / $IFS: `rm${IFS}-rf${IFS}/tmp` → expands to `rm -rf /tmp`
3. $(cmd) / `cmd` command substitution: `$(echo rm) -rf /tmp` → runs rm
4. ANSI-C quoting: `$'\\x72\\x6d' -rf /tmp` → decodes to `rm -rf /tmp`

Implementation: split normalization into two complementary passes.
_normalize_command_for_detection keeps the literal form (needed for
structural patterns like `kill $(pgrep ...)` that target the substitution
idiom itself). _expand_shell_obfuscations reverses the four tokenization
tricks. detect_dangerous_command matches every DANGEROUS_PATTERNS entry
against both forms and flags on either match.

Also strips quoted single-identifier tokens after command substitution
inlining so `$(echo 'rm') -rf` resolves correctly. The strip only fires
for shell-safe identifier content (no spaces, no metacharacters), so
legitimate quoted strings like `echo "hello world"` or
`git commit -m 'fix: update'` are unaffected.

Tests: 19 new regression tests covering all four bypass classes plus
false-positive guards for quoted log messages, grep patterns, commit
messages, curl headers, and \${PATH}-style variable expansion. The
structural `kill $(pgrep ...)` pattern added in aedf6c7 continues to
fire on the literal form.
@teknium1 teknium1 closed this Apr 21, 2026
@teknium1 teknium1 deleted the sec/approval-shell-bypass branch April 21, 2026 12:29
@teknium1 teknium1 changed the title security(approval): close shell-tokenization bypasses of dangerous command detection . Apr 21, 2026
Comment on lines +850 to +853
def test_empty_double_quote_pair_bypass_detected(self):
cmd = 'r""m -rf /tmp/foo'
dangerous, _, _ = detect_dangerous_command(cmd)
assert dangerous is True
Copy link
Copy Markdown

@latekvo latekvo Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it better to deny access based on something like ptrace? Then you don't have to worry about complex regex or edge cases like this one.
It would be more pedantic than current approaches, but i'm not sure if that's a bad thing.
The user either allows for access to files outside the project or not, if it's the latter then i don't think every case can be handled perfectly, it could be better to default to rejecting such removals/edits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants