Skip to content

build: mitigate potential script injection in promote workflow#7166

Merged
jbw976 merged 1 commit into
crossplane:mainfrom
jbw976:secure-promote
Mar 2, 2026
Merged

build: mitigate potential script injection in promote workflow#7166
jbw976 merged 1 commit into
crossplane:mainfrom
jbw976:secure-promote

Conversation

@jbw976
Copy link
Copy Markdown
Member

@jbw976 jbw976 commented Mar 2, 2026

Description of your changes

We did some repo auditing after @ytsarev shared this article about other CNCF projects github actions workflows being exploited: https://www.stepsecurity.io/blog/hackerbot-claw-github-actions-exploitation

Most of the findings for improvements are related to setting default minimal permissions for workflows, which is covered in this ongoing PR:

This PR updates the promote.yml workflow to minimize a potential script injection attack.

We now pass promote workflow inputs through environment variables instead of interpolating them directly into shell commands with ${{ }}. Direct interpolation allows shell metacharacters in input values to be evaluated, which is a script injection risk in a workflow that has access to publishing credentials.

Note that this was not a readily exploitable vector, because the promote workflow can only be manually executed by maintainers. This path would be viable only if a maintainer's credential first became compromised.

I have:

Need help with this checklist? See the cheat sheet.

Pass promote workflow inputs through environment variables instead of
interpolating them directly into shell commands with ${{ }}. Direct
interpolation allows shell metacharacters in input values to be
evaluated, which is a script injection risk in a workflow that has
access to publishing credentials.

Signed-off-by: Jared Watts <jbw976@gmail.com>
@jbw976 jbw976 requested a review from a team as a code owner March 2, 2026 11:17
@jbw976 jbw976 requested a review from phisco March 2, 2026 11:17
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 2, 2026

📝 Walkthrough

Walkthrough

A GitHub Actions workflow refactoring that replaces direct input interpolations with environment variables (VERSION, CHANNEL, and PRE_RELEASE) across multiple promotion steps, maintaining existing control flow while improving variable handling and shell parsing.

Changes

Cohort / File(s) Summary
GitHub Actions Workflow Configuration
.github/workflows/promote.yml
Introduces VERSION, CHANNEL, and PRE_RELEASE environment variables in Promote Images steps (DockerHub, Upbound, GitHub Container Registry) and Promote Artifacts to S3 step. Updates run commands to reference environment variables instead of direct input interpolations, with proper variable quoting added for shell parsing. PRERELEASE flag logic adjusted to check the new PRE_RELEASE variable.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change—mitigating script injection in the promote workflow through safer environment variable handling.
Description check ✅ Passed The description thoroughly explains the change, its security motivation, context from repo auditing, and impact scope.
Breaking Changes ✅ Passed The pull request only modifies the .github/workflows/promote.yml file, with no changes to apis/ or cmd/ directories where breaking changes are assessed.
Feature Gate Requirement ✅ Passed PR refactors GitHub Actions workflow to use environment variables instead of direct interpolation, preventing script injection attacks without introducing experimental features.

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

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
.github/workflows/promote.yml (1)

65-67: Consider centralizing repeated input env mapping at job scope.

Would you be open to defining VERSION and CHANNEL once under jobs.promote.env? It would reduce duplication and lower the chance of step-to-step drift later.

♻️ Suggested refactor
 jobs:
   promote:
     runs-on: ubuntu-24.04
+    env:
+      VERSION: ${{ inputs.version }}
+      CHANNEL: ${{ inputs.channel }}

     steps:
@@
       - name: Promote Images to DockerHub
         if: env.DOCKER_USR != ''
-        env:
-          VERSION: ${{ inputs.version }}
-          CHANNEL: ${{ inputs.channel }}
         run: nix run .#promote-images -- crossplane/crossplane "$VERSION" "$CHANNEL"
@@
       - name: Promote Images to Upbound
         if: env.UPBOUND_MARKETPLACE_PUSH_ROBOT_USR != ''
-        env:
-          VERSION: ${{ inputs.version }}
-          CHANNEL: ${{ inputs.channel }}
         run: nix run .#promote-images -- xpkg.upbound.io/crossplane/crossplane "$VERSION" "$CHANNEL"
@@
       - name: Promote Images to GitHub Container Registry
-        env:
-          VERSION: ${{ inputs.version }}
-          CHANNEL: ${{ inputs.channel }}
         run: nix run .#promote-images -- ghcr.io/crossplane/crossplane "$VERSION" "$CHANNEL"
@@
       - name: Promote Artifacts to S3
         if: env.AWS_USR != ''
         env:
           AWS_ACCESS_KEY_ID: ${{ secrets.AWS_USR }}
           AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_PSW }}
           AWS_DEFAULT_REGION: us-east-1
-          VERSION: ${{ inputs.version }}
-          CHANNEL: ${{ inputs.channel }}
           PRE_RELEASE: ${{ inputs.pre-release }}

Also applies to: 72-74, 78-80, 89-90

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/promote.yml around lines 65 - 67, Move the repeated
environment variable mappings for VERSION and CHANNEL up to the job-level by
defining them under jobs.promote.env so all steps inherit them; update/remove
the per-step env blocks (the ones currently setting VERSION: ${{ inputs.version
}} and CHANNEL: ${{ inputs.channel }} in multiple steps) to avoid duplication
and drift, ensuring the job named "promote" (and any steps referencing
VERSION/CHANNEL) use the centralized values.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.github/workflows/promote.yml:
- Around line 65-67: Move the repeated environment variable mappings for VERSION
and CHANNEL up to the job-level by defining them under jobs.promote.env so all
steps inherit them; update/remove the per-step env blocks (the ones currently
setting VERSION: ${{ inputs.version }} and CHANNEL: ${{ inputs.channel }} in
multiple steps) to avoid duplication and drift, ensuring the job named "promote"
(and any steps referencing VERSION/CHANNEL) use the centralized values.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ee5c904 and 80bc5c9.

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

Copy link
Copy Markdown
Member

@haarchri haarchri left a comment

Choose a reason for hiding this comment

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

LGTM - are we backporting to our active releases ?

@jbw976
Copy link
Copy Markdown
Member Author

jbw976 commented Mar 2, 2026

it makes sense to backport yes, but since previous versions use earthly i don't think the backport would go smoothly. i'll probably open a PR on v2.1 and then backport that PR to the other previous branches...

@jbw976
Copy link
Copy Markdown
Member Author

jbw976 commented Mar 2, 2026

I've opened #7167 for 2.1 earthly based promote workflow and added backport labels to that for v2.0 and v1.20.

@jbw976 jbw976 merged commit 4723aa0 into crossplane:main Mar 2, 2026
23 of 24 checks passed
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 2, 2026

Successfully created backport PR for release-2.2:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants