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, sogit 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). Running
dcg 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
$varpaths 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 runsrm -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 (github.com).
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.
:::bash
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