Register and share your invite link to earn from video plays and referrals.

Yonas Beshawred
@yonasbe
Co-Founder @starslingdev (agent-native CI). Prev. Founder & CEO StackShare (acq)
Joined August 2010
1.1K Following    2.3K Followers
Pinning to a SHA is the right first step. Three things to add from this thread: 1. Check that the SHA came from the action's own repo. GitHub serves a fork's commits under the original repo's name, so owner/action@ can be a stranger's code. GitHub's own hardening guide says to verify this. 2. Building on @PRaSeN_S's point: your own run: steps can pull in unpinned code too. Piping an installer straight into bash, or cloning another repo at a branch and running a script from it, both do this. 3. Also his token point: declare permissions: in every workflow, and grant write access only to the job that needs it. We open-sourced two skills that check for these. They read your workflow files locally. - ci-score reports what share of your actions are pinned to a full SHA, including your own composite actions, and gives the fix for the rest - ci-secure flags piped installers, scripts run from repos cloned at a branch, workflows with no permissions: block, workflow-wide write access, and other CI attack paths Install prompt: "Run npx skills add starslingdev/skills --skill ci-score and npx skills add starslingdev/skills --skill ci-secure, then run ci-score and ci-secure on this repo. Pin every action to a full commit SHA and fix every finding." For actions nested inside third-party actions, GitHub's workflow lockfiles (generally available as of last week, per @bnjorogedev) are the answer. Neither skill looks in there.
Show more
Hack vector we're seeing in almost every customer codebase: github actions that aren't pinned to specific versions. Github actions are build steps that run in CI and in deploy workflows. There are third party actions that do all kinds of utility operations: list changed files, log in to Docker, deploy to github pages... etc. Everyone uses them. The problem is that their behavior can change. This is code that runs in your CI that can change under you at any time. It isn't versioned by your own version control. A third party can change what these actions do whenever they want. A lot of very widely used utilities are managed by solo devs on their personal github accounts: peaceiris/actions-gh-pages, dorny/paths-filter, appleboy/ssh-action. If these github accounts get taken over, the attacker can run arbitrary code within your github runners: exfiltrate your code, steal whatever secrets are in CI, even inject code changes into deploys. A lot of github workflows pin to a version, like dorny/paths-filter@v3. This is not good enough, because those version tags can be changed at any time to point to new commits. You need to pin to a specific sha, like dorny/paths-filter@0e4a8c6effa4802afeda77dc8d303f8176d7dfad. This happened last year. Attackers compromised a popular github action. (A simple util that listed files changed in a PR.) They shipped a malicious version of the github action, and then they retroactively changed version tags like "v1.0.0" to point to that compromised code. They used this to steal secrets from 23,000 repos. This is a really broad amplification vector that will take you very little effort to avoid upfront. I'm not sure if this category of vuln even has a name, but it's a ticking timebomb. What we're doing for our own code: 1. Switch all github actions to pinned shas 2. Add a lint rule that makes sure all github workflows use pinned shas, not any other kind of version tag Both of these are oneshot-able in your agent of choice.
Show more