Skip to content

fix(security): enforce read + shell guards on @-inline and custom-command expansion - #379

Merged
Faisal-Fayaz merged 1 commit into
mainfrom
fix/at-inline-custom-shell-guards
Oct 8, 2026
Merged

Faisal-Fayaz merged 1 commit into
mainfrom
fix/at-inline-custom-shell-guards

Conversation

@Faisal-Fayaz

Copy link
Copy Markdown
Owner

Closes audit findings #1 + #2.

_expand_at_refs (agent.py) and _read_ref (custom_commands.py) used plain Path.read_text with no sensitive-path check, so @~/.ssh/id_rsa and history.db inlined straight into the prompt while read_file refused them. Both now route through _check_read_path (resolve-first, symlink-safe).

_run_shell (custom_commands.py) ran sh -c with no destructive-command check, so !rm -rf / / !curl ..|sh in a template executed pre-prompt. Now checks _check_shell first, fail-closed.

Tests: 7 new parity tests in tests/test_security.py (sensitive @-refs blocked, symlinks blocked, benign still inlines, destructive custom shell refused without execution).

Gates: 162 passed (security+custom_commands+trust+custom_command_shell), ruff + format clean, mypy clean on touched files.

…mand expansion

_expand_at_refs and custom _read_ref bypassed _check_read_path, inlining
~/.ssh, ~/.gnupg and history.db into the prompt. Route both through
_check_read_path (resolve-first, symlink-safe).

custom _run_shell bypassed _check_shell, letting !`rm -rf /` /
!`curl ..|sh` in templates execute with no approval. Check first,
fail closed.

Add parity tests: sensitive @-refs blocked, symlinks blocked,
benign inlines still work, destructive custom shell refused
without execution.
@Faisal-Fayaz
Faisal-Fayaz merged commit 4604236 into main Oct 8, 2026
12 checks passed
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.

1 participant