audit: security pass (token leaks, injection vectors, trust model, sed-rewrite hardening) #156
Labels
No labels
bump
major
bump
minor
bump
patch
kind/bug
kind/chore
kind/docs
kind/feature
priority/critical
priority/high
priority/low
priority/medium
size/L
size/M
size/S
size/XL
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit#156
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why now
Pre-1.0 readiness: the toolkit publishes to releases via API, manipulates tokens, runs user-controlled inputs (commit messages, PR titles, version strings) through shell, and
#148's planned mechanism introduces sed-based YAML rewrites. One deliberate security pass before locking in the 1.0 schema is appropriate.Audit surfaces
Token handling
echo/printf/log()lines that interpolate$GITHUB_TOKEN/$RELEASE_TOOLKIT_TOKEN/$FORGEJO_TOKEN_*/ similar. The fail-loud paths are a common forget-mode site (a stack trace shows the env).Authorization: Bearer <token>headers if-vis used. Auditforgejo-api.shspecifically.${RELEASE_TOKEN_OVERRIDE:-$GITHUB_TOKEN_DEFAULT}shape appears in multiple places (ADR-0007); confirm no fallback path silently swaps to a more-privileged token.Bash injection vectors
User-controlled inputs reaching shell:
conventional-commits.sh) — could contain backticks /$(...)if reached unquotedsemver.sh) —$NEXT_VERSIONreaches sed in #148's planned mechanismjq, then potentially interpolated)Audit each user-input → shell-interpolation path for proper quoting.
post_bump_hooks trust model
release-toolkit.yml'spost_bump_hooks:lets a consumer specify arbitrary shell commands that run during the cut. Documented trust model:Audit:
release-toolkit.ymlinjected via a PR (where the workflow runs against the PR's content) execute hooks?pull_requesttrigger's permissions vspush: mainpermissions — are they aligned with the trust model?sed-based YAML rewrites (#148)
#148's planned mechanism uses sed to rewrite the
ref:value in_release.yml:Audit:
$NEXT_VERSIONcontains|(sed delimiter)?'(string boundary)? Shell metacharacters?$NEXT_VERSIONcomes from semver-derived strings; should bev[0-9.]+(-rc.[0-9]+)?. Confirm the sanitization is enforced + documented.$NEXT_VERSION=...|;rm -rf /;|...via env), what's the blast radius?Consumer config trust model
release-toolkit.ymlis read by the toolkit's scripts. Confirm:config.sh) doesn'tevalorsourceconsumer-provided valuesversion_files: [...]are validated (path traversal? glob expansion?)release_typeenum is validated (no fall-through to arbitrary string)Composition
Implementation surface
Audit-only PR (no code changes) producing:
docs/security.mdsummarizing the audit findingsIf vulnerabilities are found: tracker-each + remediate in follow-up PRs (don't bundle the audit doc with fixes).
Estimated scope: 1-2 days of focused work + however many follow-up trackers materialize.
What this PR does NOT do
Refs
quartermaster referenced this issue2026-06-27 14:27:35 +02:00
Closing — security audit umbrella. Sub-items shipped:
lib/build_bake.sh::bake_toolkit_ref— ref-shape allowlist[A-Za-z0-9._/-]+)lib/config.sh::config_validate— rejects absolute paths +..boundary patterns)No additional security vectors surfaced beyond these during the audit pass. Ongoing chamber-discipline (substrate-state-care + Surveyor's verify-at-source on each PR review) keeps the security mindset present in normal review flow. If a new vector surfaces empirically, fresh tracker.
Operator confirmation: no remaining security gaps to close (2026-06-28).