ci: address CodeQL security findings (cache poisoning + permissions)#31
Conversation
14 alerts surfaced after CodeQL was enabled. Two classes: **Cache poisoning (7 alerts, High severity)** — `actions/cache@v5` was used in `setup-build-environment` from workflows that run under `pull_request_target`. That context runs untrusted PR code with the default branch's secrets/permissions, so a malicious PR could write a poisoned build cache that later trusted runs on `dev` would restore. Fix in `.github/actions/setup-build-environment/action.yaml`: split the single combined cache step into two conditionally-invoked steps that share the same cache key: - Trusted events (push, workflow_dispatch, workflow_call from release pipeline) keep the combined `actions/cache@v5` — restore at this step, auto-save at job-end. - Untrusted events (`pull_request`, `pull_request_target`) use the restore-only sub-action `actions/cache/restore@v5`. PR builds still benefit from caches warmed by trusted runs but cannot themselves write back. Trust crosses the boundary in only the safe direction. **Missing workflow permissions (7 alerts, Medium severity)** — three workflows ran with implicit full-scope GITHUB_TOKEN. Add explicit least-privilege `permissions:` blocks: - `nexus-upload.yaml`: workflow-level `contents: read`. Every job only reads from GitHub (release listing via `gh api`, asset download via `gh release download`) and writes only to Nexus via UNEX_* secrets. - `pr-wip.yaml`: `statuses: write` + `pull-requests: read` for the wip/action's commit-status set + PR metadata read. - `maint-todo-issues.yaml`: `contents: read` for checkout + `issues: write` for the create-issue call.
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Pull request overview
This PR hardens the repository’s CI against CodeQL-reported GitHub Actions risks by preventing cache writes from untrusted PR contexts and by applying least-privilege GITHUB_TOKEN permissions to affected workflows.
Changes:
- Split the CMake build cache step in the
setup-build-environmentcomposite action into trusted (restore+save) vs untrusted (restore-only) variants to eliminate cache-poisoning risk. - Add explicit least-privilege
permissions:blocks to workflows that previously relied on implicit default token scopes. - Document the intent of the permission scopes and the cache trust-boundary behavior inline in workflow/action YAML.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
.github/workflows/pr-wip.yaml |
Adds explicit minimal permissions for wip/action (commit status write + PR metadata read). |
.github/workflows/nexus-upload.yaml |
Sets workflow-level contents: read to avoid implicit broad token permissions while using gh to read releases/assets. |
.github/workflows/maint-todo-issues.yaml |
Sets minimal permissions needed for checkout + creating issues from TODO/FIXME markers. |
.github/actions/setup-build-environment/action.yaml |
Prevents untrusted PR-triggered jobs from saving caches while still allowing cache restore for speed. |
Summary
Addresses all 14 open code-scanning alerts surfaced after CodeQL was enabled.
actions/cache-poisoning/poisonable-stepinpr-checks.yamland_shared-build.yaml. PR builds running underpull_request_targethad write access to a cache later restored by trusted default-branch runs.actions/missing-workflow-permissionsinnexus-upload.yaml,pr-wip.yaml,maint-todo-issues.yaml. Workflows ran with implicit full-scopeGITHUB_TOKEN.Cache poisoning fix
setup-build-environment/action.yaml: split the single combined cache step into two conditionally-invoked steps that share the same key:push,workflow_dispatch,workflow_call)actions/cache@v5pull_request,pull_request_target)actions/cache/restore@v5PR builds still get the cache speedup (restoring caches warmed by trusted runs) but can't write back to them. Trust crosses the boundary in only the safe direction.
Permissions fix
Per-workflow least-privilege blocks:
nexus-upload.yamlcontents: read(workflow-level)gh api/gh release download. Writes go to Nexus via UNEX_* secrets, not GitHub.pr-wip.yamlstatuses: write,pull-requests: readmaint-todo-issues.yamlcontents: read,issues: writeVerification
Once merged, the 14 alerts should auto-close on the next CodeQL run against
dev. No other alerts expected from this change.Test plan
pr-checks.yamlruns and the PR build still gets a cache restore (look forCache restored from key:in theRestore CMake build cache (untrusted PR, restore-only)step).Cache CMake build output (trusted, restore + save)skipped in the step list.dev, the next push-triggered build should populate/save the cache normally.devshows 0 open alerts.🤖 Generated with Claude Code