Skip to content

fix(approval): allow quoted shell metacharacters in allowlist matching (port of oh-my-pi#7553) - #80830

Merged
teknium1 merged 1 commit into
mainfrom
omp-port/allowlist-quoted-metachars
Aug 17, 2026
Merged

fix(approval): allow quoted shell metacharacters in allowlist matching (port of oh-my-pi#7553)#80830
teknium1 merged 1 commit into
mainfrom
omp-port/allowlist-quoted-metachars

Conversation

@teknium1

@teknium1 teknium1 commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Summary

command_allowlist glob rules (e.g. cargo *) now match commands whose quoted arguments contain shell metacharacters — previously cargo bench -- '^layer3/write/(a|b)$' was rejected as "compound" even though every metacharacter is literal to the shell.

Port of can1357/oh-my-pi#7553 (their issue #7552). Our _has_allowlist_shell_operator used a flat regex ([;&|<> ]|\$\() with no quote awareness, so any benchmark filter, grep pattern, or commit message containing |, ;, (, $ disqualified the whole command from the allowlist shortcut and forced an approval prompt the user had already opted out of.

Security posture (unchanged or tightened)

  • Unquoted ; & | < > $( ` and newlines: rejected exactly as before.
  • $/backtick inside double quotes: rejected (expansion is active there).
  • Quoted/escaped control chars + a -c/-e/--command/--eval-style option: rejected — sh -c '...' and git -c alias.x='!...' x hand the quoted payload to another interpreter (this closes a hole the old regex also had for backslash-escaped payloads like git -c alias.x=\!touch\ /tmp/pwn\;\ ok x — the old regex caught the ; but the reinterpretation class is now handled explicitly).
  • Unterminated quotes: rejected (can't reason about the shape).
  • hermes approvals suggest's derive_glob inherits the same semantics via its existing import.

Changes

  • tools/approval.py: quote-aware scanner replaces _ALLOWLIST_SHELL_OPERATOR_RE
  • tests/tools/test_allowlist_quoted_metachars.py: 24 new tests (literal-quote acceptance, compound rejection, interpreter-option payloads, unterminated quotes, end-to-end glob matching)

Validation

Before After
cargo bench -- '^a(10|1000)$' vs cargo * prompt allowed
cargo build && rm -rf /tmp/x vs cargo * blocked blocked
git -c alias.x='!touch /tmp/pwn' x vs git * blocked blocked
approval + suggest + deny-rule suites 149 passed

Infographic

allowlist-quotes

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on 614def0 — Port from can1357/oh-my-pi#7553: allow quoted shell metachar

⚠️ Warnings

CI timings · View report · View job

Wall time 28m23s vs 8m (+254.8%). 18 job(s) slower, 5 faster, 1 unchanged.

  • Python tests / Run tests slice 7/12: -39.0s
  • Python tests / Run tests slice 1/12: +39.0s
  • Python tests / Run tests slice 4/12: -21.0s
  • Python tests / Run tests slice 8/12: +17.0s
  • Python tests / Run tests slice 9/12: +16.0s

OSV vulnerability scan · View job

5 known vulnerabilities found in pinned dependencies.

How to fix:

Review the findings in the Security tab. Update the affected dependencies if a patched version is available.

@alt-glitch alt-glitch added type/bug Something isn't working tool/terminal Terminal execution and process management P2 Medium — degraded but workaround exists sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data labels Aug 7, 2026
… allowlist matching

command_allowlist glob rules (e.g. 'cargo *') rejected any command whose
quoted arguments contained shell metacharacters — a cargo benchmark
regex filter like '^layer3/write/(a|b)$' disqualified the whole command
even though those characters are literal to the shell.

_has_allowlist_shell_operator is now quote-aware:
- metacharacters inside single/double quotes or behind a backslash are
  treated as literal arguments;
- $ and backtick inside DOUBLE quotes still disqualify (expansion is
  active there);
- quoted/escaped control characters still disqualify when the command
  carries a -c/-e/--command/--eval-style option that hands the payload
  to another interpreter (sh -c '...', git -c alias.x='!...' x);
- unterminated quotes disqualify (shape can't be reasoned about).

Compound commands (unquoted ; & | < > backtick $( newline) are rejected
exactly as before. hermes_cli/approvals_suggest.derive_glob picks up the
same semantics via its existing import.
@teknium1
teknium1 force-pushed the omp-port/allowlist-quoted-metachars branch from 12dd7d8 to 614def0 Compare August 17, 2026 02:58
@teknium1
teknium1 merged commit 66312ae into main Aug 17, 2026
45 checks passed
@teknium1
teknium1 deleted the omp-port/allowlist-quoted-metachars branch August 17, 2026 05:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Medium — degraded but workaround exists sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data tool/terminal Terminal execution and process management type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants