fix(ci): split release-please lockfile pipeline (codeql untrusted-checkout/critical)#21
Conversation
…ckout/critical) The previous one-workflow design checked out a release-please PR branch inside a workflow_run context with contents: write and ran cargo check on it. CodeQL flags that as critical (alert #18, actions/untrusted-checkout/critical) because a privileged workflow_run job must never execute code from a non-default ref — the gh pr list author + branch-prefix gate is a soft filter, not a security boundary, since CodeQL treats any non-default ref as untrusted-by-default. Split into the canonical two-workflow pattern: - release-please-lockfile-build.yml (NEW, pull_request, contents: read): checks out the PR branch, runs cargo check, uploads the refreshed Cargo.lock + PR metadata as a 1-day artifact. Runs unprivileged so executing release-please's Cargo.toml / Cargo.lock through cargo can't reach secrets or push. - release-please-bump-lockfile.yml (REWRITTEN, workflow_run, contents: write): no actions/checkout of the PR branch, no cargo invocation. Downloads the artifact, validates the Cargo.lock header + size envelope, re-fetches the PR via the API to confirm it's still open, authored by github-actions[bot], on the same head SHA the artifact was built against, then pushes the lockfile via the Git Data API (createBlob -> createTree -> createCommit -> updateRef). Head-SHA check ensures we never push a Cargo.lock generated against a stale Cargo.toml — if the bot pushed a follow-up while the build was running, we skip and let the next build-workflow artifact carry the fresh lock.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThis PR splits Cargo.lock refresh into two workflows: an unprivileged build that regenerates ChangesCargo.lock Refresh Pipeline for release-please PRs
Estimated Code Review Effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption. Comment |
…ontrolled)
github-advanced-security flagged the artifact staging step: pull
request branch names go through ${{ github.event.pull_request.head.ref }}
interpolation BEFORE the shell sees the line, so a branch named
e.g. $(curl evil) would execute as code. Move every PR-metadata
value behind an env: block so they're shell variables, then
emit them with printf '%s' (no trailing newline, no surprise
interpretation).
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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-please-lockfile-build.yml:
- Around line 84-89: The workflow currently interpolates the attacker-controlled
value github.event.pull_request.head.ref directly into the shell, creating a
command injection risk; change the step to pass that value as an environment
variable (e.g., PR_BRANCH set to ${{ github.event.pull_request.head.ref }}) and
then write it to artifact/pr_branch using a safe printer like printf '%s'
"$PR_BRANCH" > artifact/pr_branch; update the step to use the env-var name
(PR_BRANCH) instead of direct interpolation and likewise prefer printf '%s' for
any other interpolated pull_request fields you write (e.g., pr_head_sha) to
avoid interpretation of special characters.
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 3258ac47-c077-4870-9716-d2aff09ba019
📒 Files selected for processing (2)
.github/workflows/release-please-bump-lockfile.yml.github/workflows/release-please-lockfile-build.yml
Summary
Closes CodeQL alert #18 (
actions/untrusted-checkout/critical— Checkout of untrusted code in a privileged context) on.github/workflows/release-please-bump-lockfile.yml.The previous design ran inside a
workflow_runprivileged context (contents: write) and explicitly checked out a release-please PR branch, then rancargo checkon it. CodeQL'scriticalrule fires because any privilegedworkflow_runjob must not execute code from a non-default ref — author + branch-prefix gates are soft filters, not security boundaries.The fix: canonical two-workflow split
release-please-lockfile-build.yml(NEW,pull_request,contents: read) — checks out the PR branch in unprivileged context, runscargo check, uploads the refreshedCargo.lock+ PR metadata (pr_number/pr_branch/pr_head_sha) as a 1-day artifact. Any code execution that happens here (build scripts, proc macros) cannot reach secrets or push.release-please-bump-lockfile.yml(REWRITTEN,workflow_run,contents: write) — noactions/checkoutof the PR branch, nocargoinvocation. Downloads the artifact, validates theCargo.lock(header pattern + size envelope), re-fetches the PR via API to confirm it's still open + authored bygithub-actions[bot]+ same head SHA the artifact was built against, then pushes via the Git Data API (createBlob→createTree→createCommit→updateRef).Defense in depth
cargo checkon every PR).Test plan
cargo check, uploads artifactchore: bump Cargo.lockcommit alongside the version bumpSummary by CodeRabbit