A safety release. Most of this release fixes commands that v0.14.4 allowed
and should have blocked. The minor version bump is because several of those fixes
change verdicts you may see day to day; nothing was removed from the
configuration or the hook protocols.
In short:
- A warning no longer hides a later block (#498). A rule set to
warn,
logoraskused to be the whole answer for the command line, so
git stash drop && git reset --hardwas allowed. dcg now keeps looking past
a non-blocking match and reports the strictest result. - Credential and startup files are protected wherever the home directory
lives (#502). Synology (/volume1/homes/<u>,/var/services/homes/<u>),
/var/home,/usr/home,/export/home, a container's own$HOME, macOS
firmlinks, WSL and Cygwin mounts of a Windows profile, and many spellings of
those paths (quotes,./.., globs, brace lists, ANSI-C escapes) are now
recognised. Review rounds on this fix found and closed a long list of
further bypass classes, listed under Security below. - The PowerShell profile check stops warning "Hook missing" when the hook is
installed (#503). Runningdcg installrewrites an old profile block in
place, and paths containing''(for exampleO''Brien) are read
correctly. - Commands handed to another program to run are judged.
watch '…',
su -c '…',parallel ::: '…',env -S'…',flock -c,nix-shell --run,
ssh host …,docker execand similar runners and wrappers pass their
command through dcg the waysh -c '…'always did. - A redirect or option no longer hides
sh -c's script.
sh 2>/dev/null -c '…',bash -c -e '…',sh <<<x -c '…',
powershell 2>&1 -EncodedCommand …and similar spellings are judged. - Pathological input fails closed quickly instead of stalling the hook.
Very long pipelines, long runs of unclosed brackets, deep glob or$var
paths and exponential glob patterns are bounded.
Behaviour changes you may notice:
- A pipeline of more than 1,024 stages is denied without being parsed
(heredoc.shell:analysis-bounds). - A write target whose path has more than 64 components that the shell can
rewrite (/*/*/…,/$x/$x/…) is denied as a possible credential-file write. ssh host git commit -m 'rm -rf x'is now denied. ssh joins its arguments
and the remote shell re-parses them, so the remote side really runs
rm -rf x. Quote the whole remote command
(ssh host "git commit -m 'rm -rf x'") if you mean the message.- An unquoted heredoc body that contains a command-string runner, such as
cat > notes.md <<EOFwithwatch 'git reset --hard'inside, can be denied,
assh -c '…'in the same place already was. Quote the delimiter
(<<'EOF') for text that is only data. - Rules that were warn-only in your
[policy]no longer let later deny rules
on the same line through. A line that only matches a warn rule is still a
warn.
The complete list of fixes, with the exact spellings each review round found, is in CHANGELOG.md.
Assets
Six archives, each holding only the dcg binary (dcg.exe on Windows): x86_64-unknown-linux-musl (static), aarch64-unknown-linux-gnu (glibc 2.28 or newer), x86_64-apple-darwin, aarch64-apple-darwin, x86_64-pc-windows-msvc, aarch64-pc-windows-msvc. Every archive and both installers have a .sha256, a minisign signature (key 69B3955C8D2E62A8, the key pinned in install.sh, install.ps1 and release/minisign.pub) and a key-based Sigstore bundle (.sigstore.json, the installers' pinned cosign key). SHA256SUMS is signed with the same minisign key.
V=v0.15.0; T=aarch64-apple-darwin # or x86_64-unknown-linux-musl, etc.
curl -fLO "https://github.com/Dicklesworthstone/destructive_command_guard/releases/download/$V/dcg-$T.tar.xz"
curl -fLO "https://github.com/Dicklesworthstone/destructive_command_guard/releases/download/$V/dcg-$T.tar.xz.minisig"
minisign -Vm "dcg-$T.tar.xz" -P RWSoYi6NXJWzaRs1mJmOwwXrZfPWcq6MXnQlNMLBYKzlIQTLwuVQG6uO