fix(security): pin Semgrep CI container image by SHA digest [DEVA11Y-476] - #15
Merged
Merged
Conversation
F-004 / DEVA11Y-476 — The Semgrep workflow used an unpinned image tag (CWE-829), enabling tag-poisoning attacks. Pin to SHA256 digest. This is the chain-breaker for C-001 (DEVA11Y-485, CVSS 10.0). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Crash0v3rrid3
approved these changes
May 27, 2026
Crash0v3rrid3
added a commit
that referenced
this pull request
Aug 28, 2026
…A11Y-476] (#38) * chore(deps): add Dependabot to rotate the pinned Semgrep CI image (DEVA11Y-476) The Semgrep workflow container image is already pinned by immutable @sha256 digest (PR #15), which is the DEVA11Y-476 chain-breaker for the C-001 chain (DEVA11Y-485: CI image compromise -> mutable main -> SPM plugin RCE). A static digest, however, never receives upstream security patches — the current pin already lags returntocorp/semgrep:latest. Add .github/dependabot.yml with a `docker` ecosystem entry over /.github/workflows so Dependabot bumps the pinned digest to the newest build on a weekly cadence, keeping immutability without freezing the image. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(ci): add cooldown to Dependabot Semgrep image updates Adds a release-age cooldown so Dependabot does not adopt a freshly-published returntocorp/semgrep digest immediately — a poisoned-image would otherwise be pulled in within a day of publication, the exact window digest-pinning is meant to defend (DEVA11Y-476 / chain DEVA11Y-485). Also resolves the semgrep/ci finding flagging the update config for lacking a minimum release age. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(ci): rotate GitHub Actions via Dependabot + drift-alarm the Semgrep image Dependabot's `docker` ecosystem cannot discover a `container:` image ref in a workflow file (dependabot-core#5819), so the previous `docker`/`/.github/workflows` config would never rotate the pin and would fail a weekly Dependabot job. Pivot: - dependabot.yml: replace the unusable `docker` entry with a `github-actions` entry (directory "/", weekly, cooldown default-days 7) — real, supported rotation for the action `uses:` pins here, several of which are 3 years stale. Drop the undefined `security` label and the redundant open-pull-requests-limit. Cooldown retained (also clears the semgrep/ci dependabot-missing-cooldown rule). - Add semgrep-image-pin-drift.yml: read-only scheduled/dispatch job that alarms (fails) when the pinned returntocorp/semgrep@sha256 digest drifts from :latest, keeping a human in the loop on the image bump (better for the C-001 threat model than auto-adopting latest). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(ci): address PR#38 round-2 review (cooldown/drift/pin/guard) Resolves Nishant's second review on PR #38: 1. cooldown is inert for the github-actions Dependabot ecosystem — kept only to satisfy Semgrep's dependabot-missing-cooldown rule; documented as inert in dependabot.yml (no real release-age protection for action bumps). 2. Semgrep image drift workflow: made the intended-failure branches reachable under GHA's injected `bash -e` (|| true on the grep/token/latest command substitutions + explicit empty-token guard), same class of fix as #37 66249fe. Verified: happy/stale/pin-removed/registry-down all annotate+exit. 3. Reworked the alarm from "differs from :latest" (red most weeks → muted) to "pinned image older than 45 days" (actionable). Bumped the Semgrep image pin to the current :latest digest so it lands green: f682953… -> f1f7b71861c7b28b6e0f661225a2c4f58a484f5d0f182465c6d6b3b22f972ade (created 2026-08-20, ~8 days old). 4. Removed the job-level `if: github.actor != 'dependabot[bot]'` guard on Semgrep.yml and scoped it to only the privileged upload-sarif step, so Dependabot PRs that bump the action pins living in Semgrep.yml still get scanned; only the security-events:write SARIF upload is skipped for them. Also documented the scheduled-workflow ops caveat (60-day inactivity disable; failed runs notify only the last cron editor) in the drift workflow. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
returntocorp/semgrepwith no tag or digest — any upstream tag mutation would silently alter the CI environment.returntocorp/semgrep@sha256:f682953ce85e3725f4a4dd94bd7ad13e570bb6b2c7a8cf7c6e38a9eac89239b2(latest amd64 as of 2026-05-26).Verification
.github/workflows/Semgrep.ymlline 31 contains@sha256:(no bare tag).Jira
🤖 Generated with Claude Code