Repository navigation
chore: validate the release tag and build the scribe dispatch payload with jq - #193
Conversation
… with jq Git allows " in tag names, so a crafted v* tag could add fields to the repository_dispatch JSON sent to doiteng/scribe with SCRIBE_DISPATCH_TOKEN. The release job now rejects tags outside vMAJOR.MINOR.PATCH[-PRERELEASE] before checkout, later steps read the checked RELEASE_TAG, and the payload is built with jq --arg. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Looks good — straightforward CI hardening change.
What was reviewed: the new tag-validation regex and its placement (runs first, before checkout, so it gates every later step); the switch from three independent GITHUB_REF parses to a single RELEASE_TAG export; the scribe dispatch payload change from manual string interpolation to jq -cn, which closes the tag-injection risk the PR describes (a " in a tag could previously add fields to the client_payload). No issues found.
Extended reasoning...
Single-file change to .github/workflows/release.yml: adds a tag-format validation step and centralizes tag extraction into $RELEASE_TAG, and swaps manual JSON string-building for jq in the scribe repository_dispatch call. Security-sensitive surface is the untrusted-tag-to-JSON-payload path (a crafted tag could previously inject fields into a dispatch sent with a secret token); jq -cn with --arg correctly neutralizes that, and the new regex additionally rejects malformed/malicious tags up front. The change is small, mechanical, CI-only, matches the repo's chore: commit convention for non-user-facing CI fixes, and has no open reviewer objections in the PR timeline, so a human need not re-review.
Summary
Git allows
"in tag names.release.ymlbuilt therepository_dispatchJSON for doiteng/scribe by pasting the tag into a string, so a craftedv*tag could add fields to the payload sent withSCRIBE_DISPATCH_TOKEN. This is the "Release dispatch JSON" follow-up listed in #191.Changes
.github/workflows/release.yml^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z]+(\.[0-9A-Za-z]+)*)?$, the same pattern chore: stop release tag from reaching shell, sed, and manifests unvalidated #191 adds tosync-manifests.ymlandpost-release-verify.yml. A tag that passes is exported asRELEASE_TAG.$RELEASE_TAG. Nothing parsesGITHUB_REFafter the check any more.jq -cn --arg tag "$RELEASE_TAG" '{...}', so it's safe even without the check.Testing
actionlintpasses.v*tag matches the pattern, and so doesv2.8.0-rc.1.","client_payload":...injection,$(id), a tag with an embedded newline (which would otherwise add a line toGITHUB_ENV), andv1.2.3-...Note
The step's comment says the check matches the one in
sync-manifests.ymlandpost-release-verify.yml. That's only true once #191 merges.🤖 Generated with Claude Code