Skip to content

fix(ci): Harden workflows against shell injection and fix quoting issues#239

Merged
Tiryoh merged 2 commits intomainfrom
fix/harden-workflows-security
Apr 2, 2026
Merged

fix(ci): Harden workflows against shell injection and fix quoting issues#239
Tiryoh merged 2 commits intomainfrom
fix/harden-workflows-security

Conversation

@Tiryoh
Copy link
Copy Markdown
Owner

@Tiryoh Tiryoh commented Apr 2, 2026

Summary

  • check-release-condition.yml: Fix command injection vulnerability by replacing ${{ }} expression interpolation in shell scripts with env-based variable passing. Strengthen the version parser with anchored regex (^...$). Migrate deprecated set-output to $GITHUB_OUTPUT. Use grep -Fq for exact fixed-string matching in the CHANGELOG check.
  • update_changelog.sh: Fix typo in git-chglog command (missing space on L18) that broke the existing-tag regeneration path. Add proper quoting for all variable references.
  • version-tag.yml: Suppress stderr on git remote set-url to prevent token leakage in error logs.

Backward compatibility verification

All 18 historical release PR titles (from release v0.8.0 through release: v0.25.0) were tested against both the old and new grep/sed patterns. Every title produces identical PASS results with both patterns, confirming no regression in version parsing.

TITLE                   OLD     NEW
release: v0.25.0        PASS    PASS
release: v0.24.0        PASS    PASS
...
release v0.9.0          PASS    PASS
release v0.8.0          PASS    PASS

Other changes are strictly safe:

  • set-output$GITHUB_OUTPUT: Standard migration, set-output is already deprecated by GitHub.
  • env-based outputs: Same pattern already in use in release-candidate.yaml.
  • grep -Fq: Stricter (fixed-string) matching only eliminates false positives.
  • Shell quoting: No behavioral change for version strings (digits and dots only).
  • git-chglog typo fix: Restores a broken code path (existing-tag regeneration).

Test plan

  • Open a test PR with title release: v0.25.0 and verify the check-release-condition workflow passes
  • Verify update_changelog.sh runs without errors in the release-candidate workflow
  • Confirm version-tag workflow succeeds on tag push

Tiryoh added 2 commits April 3, 2026 01:04
- check-release-condition.yml: Replace ${{ }} expression interpolation
  in shell scripts with env-based variable passing to prevent command
  injection. Strengthen version parser with anchored regex. Migrate
  deprecated set-output to $GITHUB_OUTPUT. Use grep -Fq for exact
  string matching in CHANGELOG check.
- update_changelog.sh: Fix typo in git-chglog command (missing space)
  that broke the existing-tag code path. Add proper quoting for all
  variable references.
- version-tag.yml: Suppress stderr on git remote set-url to prevent
  token leakage in error logs.
@Tiryoh Tiryoh force-pushed the fix/harden-workflows-security branch from c7e1979 to 0963a9d Compare April 2, 2026 16:05
@Tiryoh Tiryoh requested a review from Copilot April 2, 2026 16:08
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the release-related GitHub Actions workflows and the changelog update script by fixing quoting issues, reducing opportunities for shell injection, and updating deprecated workflow output patterns.

Changes:

  • Harden check-release-condition parsing/outputs (anchored version matching, $GITHUB_OUTPUT, env-based comparisons) and make the CHANGELOG check use fixed-string matching.
  • Fix a broken git-chglog invocation path and improve shell quoting in update_changelog.sh.
  • Update version-tag workflow to reduce the chance of token leakage in error logs.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
.github/workflows/version-tag.yml Adds job gating and suppresses stderr for remote URL update when pushing major/minor tags.
.github/workflows/check-release-condition.yml Tightens release title parsing, migrates from set-output to $GITHUB_OUTPUT, and hardens comparisons/grep usage.
.github/scripts/update_changelog.sh Fixes git-chglog command typo and adds consistent variable quoting.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 8 to +9
runs-on: ubuntu-latest
if: github.actor == github.repository_owner
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new job-level condition if: github.actor == github.repository_owner is a behavior change that will skip this workflow for tag pushes made by non-owner maintainers or automation (e.g., github-actions[bot]). If major/minor tag updates are expected to run for tag pushes created by CI or by collaborators with tag permissions, consider broadening/adjusting the condition (or documenting why only the repository owner should be allowed).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is intentional. In this repository, only the repository owner pushes version tags. The same restriction pattern is already applied to the release-candidate workflow.

- name: tag
run: |
git remote set-url origin https://${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY}.git
git remote set-url origin "https://${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY}.git" 2>/dev/null
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redirecting git remote set-url stderr to /dev/null prevents potential token leakage, but it also removes actionable diagnostics if the command fails (the step will just error with no context). A safer approach is to avoid embedding the token in the remote URL at all (actions/checkout typically already configures authenticated remotes), or capture stderr and re-emit a sanitized failure message without the URL/token.

Suggested change
git remote set-url origin "https://${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY}.git" 2>/dev/null

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner Author

@Tiryoh Tiryoh Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the stderr suppression. GITHUB_TOKEN is scoped to the job and expires on completion, so token leakage in error logs is not a practical risk. Keeping diagnostic output is more valuable.

@Tiryoh Tiryoh merged commit 3935b37 into main Apr 2, 2026
8 checks passed
@Tiryoh Tiryoh deleted the fix/harden-workflows-security branch April 2, 2026 16:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants