Repository navigation
Close wrapper, deferred-command and stack-overflow bypasses in deniedBy - #1
Merged
Merged
Conversation
An audit found lines that ran a denied command while deniedBy returned null, and a deeply nested line that threw a RangeError, which a hook that fails open on errors would let through. - Catch stack overflow while reading and report the line as unreadable. - Move wrapper option tables to wrappers.ts and add chrt, taskset, caffeinate, arch, unbuffer, strace, ltrace, nsenter, chroot, pkexec, run0, runuser, su -c, systemd-run, firejail, faketime, dbus-launch, xvfb-run, toybox, script, parallel, fd -x, ssh, yarn exec, bun x/exec, coproc, function, and zsh's =cmd, noglob, nocorrect, - and [[ ]] cmd. - Read commands set up to run later: trap actions, alias values, git rebase -x, difftool -x, bisect run, submodule foreach, filter-branch filters and git -c values; deny git config alias.*. - Treat the words xargs and parallel add, and xargs' replace-string, as expansions. - Deny source of stdin or a process substitution. - Search interpreter inline programs (python -c, node -e, perl -e, awk, ...) for a pattern's words. - Fold //, /./ and trailing / or /. in rm operands. - Add pkexec, run0 and rm -rf ~/* to DEFAULT_DENY.
Attached short-option values (-c'code', -x'cmd'), flock -c before the lock file, ssh options after the host, GNU time -f/-o, env -a/-P, clustered xargs -I, missing value options for parallel, npx and systemd-run, `..` in rm operands, versioned interpreter names, eval --, and gtimeout, fakeroot, unshare, sandbox-exec and similar launchers.
3 of 5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
An audit of
deniedByfound about 65 command lines that run a denied command while the guard returnednull, and one input that made it throw instead of returning a verdict.'$('.repeat(20000)) threw aRangeError. APreToolUsehook that treats an error as "no decision" would have let the command run. The line is now reported as unreadable ('unbalanced quoting').chrt,taskset,caffeinate,arch,strace,ltrace,nsenter,chroot,pkexec,run0,runuser,su -c,systemd-run,script,parallel,fd -x,ssh host …,yarn exec,bun x/bun exec,gtimeout,fakeroot,unshare,sandbox-exec,coprocandfunctionbodies. The zsh-only forms=cmd,noglob,nocorrect,-and[[ … ]] cmdare read in strict mode only.trapactions,aliasvalues,git rebase -x,git difftool -x,git bisect run,git submodule foreach,git filter-branchfilters, andgit -cvalues such as a pager, editor or ssh command.git config alias.*is denied.xargsandparalleladd count as expansions. This coversecho push | xargs gitandxargs -I{} sh -c {}, including a replace-string inside an option cluster.sourceof stdin or a process substitution is denied.sourceof a regular file is still allowed, as./scriptis, so thatsource .venv/bin/activatekeeps working.python -c,node -e,perl -e,ruby -e,php -r,osascript -e,awkand similar is searched for a pattern's words. This is a heuristic and the README says so.rmoperands are folded.//,/./, a trailing/or/., and..are folded before matching.-c'code') are read,sshoptions after the host are skipped, and GNUtime -f/-oandenv -a/-Ptake their value.DEFAULT_DENYgrows. It addspkexec,run0andrm -rf ~/*.src/wrappers.ts.The README now compares against agent hooks (git-guardrails, dcg). It also documents the new limits.
Known gaps
null:setpriv,xcrun,direnv exec,op run,mise exec.rm -rf ~/..is denied as~. That is stricter than needed, because resolving above~would need the real home path.Test plan
pnpm test: 477 pass. Each closed bypass has a regression test, and the allowed everyday commands have tests too.pnpm typecheck,pnpm lintandpnpm buildpass, and publint is clean.DEFAULT_DENYfor these common commands:source .venv/bin/activate,xargs wc -l,python -c "print(1)",ssh host uptime,git rebase -i,trap "rm -f $tmp" EXIT,alias ll='ls -la'.