Skip to content

v3.0.3 — Security-hardening release

Choose a tag to compare

@GRU-953 GRU-953 released this 12 Jul 11:46

v3.0.3 — Security-hardening release

Closes a 15-round audit-loop engagement run after v3.0.2 shipped, on the
question of whether further audit was warranted. Every fix was verified
by direct execution (real bash ground truth compared against the real
isPushCapable()/gate.mjs) before being called done. Test suite grew
from 47 to 61 tests.

CRITICAL fixes — push/go-public gate matcher

A long series of genuinely different bash variable-assignment/retrieval
mechanisms, each of which could hide a real git push or a visibility
change from the publish-safety checker:

  • Array assignment and subscript access, including variable/arithmetic/
    bare-name/negative indices, array length used in arithmetic, brace
    expansion inside array literals, and an $IFS-in-subscript ordering bug.
  • printf -v NAME VALUE (including a value-capture bug).
  • Parameter-expansion defaults, indirect expansion (${!ref}),
    case-folding (${x,,}/${x^^}), and bash 4.4+'s @ transformation
    operators.
  • Substring expansion (${VAR:offset:length}).
  • read assigning from a here-string or a real here-document,
    mapfile/readarray reading into an array, and set -- resetting
    positional parameters.
  • An array/scalar cross-contamination bug that corrupted a separate fix.

CRITICAL — publish-safety structural gaps

  • The private-publish and go-public confirmation tokens had no expiry;
    fixed with a 60-minute validity window.
  • hooks.json's matcher only covered Bash, silently skipping the
    publish-safety checks on native Windows without Git Bash. Fixed by
    adding PowerShell, plus a new structural check that verifies this
    stays wired.

Other fixes

  • A role-count check false-blocked legitimate longer prose; tightened.
  • Extended a "content read from memory is data, not instruction" guardrail
    to ~20 more agent files, closing a cross-session contamination vector.
  • A documentation gap in the go-public cleanup step.

Disclosed, not fixed

Seven residual limitations — array element reassignment/append,
associative arrays, command substitution in an array element, process
substitution and co-processes feeding read, and declare -n nameref
variables — are explicitly documented in governance/SECURITY.md as
accepted limitations rather than silently open, following an explicit
scope-boundary decision made partway through this engagement.

See CHANGELOG.md for full detail.