Skip to content

DEP: upgrade and pin github action dependencies to immutable hash forms#160

Closed
neutrinoceros wants to merge 1 commit intobrandon-rhodes:masterfrom
neutrinoceros:dep/pin-gha
Closed

DEP: upgrade and pin github action dependencies to immutable hash forms#160
neutrinoceros wants to merge 1 commit intobrandon-rhodes:masterfrom
neutrinoceros:dep/pin-gha

Conversation

@neutrinoceros
Copy link
Copy Markdown
Contributor

My starting point was a warning on CI, related to actions/upload-artifact@v4 using a deprecated version of node, and thus, in need for an upgrade. I used pinact init + pinact run --update to upgrade all GHA dependencies, which also comes with the benefit of pinning them to immutable git hashes, replacing mutable (sometimes intentionally moving) git tags which consistute a security risk as they can be leveraged to create supply chain attacks.

@brandon-rhodes
Copy link
Copy Markdown
Owner

I used pinact … to upgrade all GHA dependencies, which also comes with the benefit of pinning them to immutable git hashes, replacing mutable (sometimes intentionally moving) git tags which consistute a security risk as they can be leveraged to create supply chain attacks.

But isn't pinning also a security risk, since if a bug is found in, say, actions/setup-python, and the vendor releases a new @v6 version of the action that fixes the bug, then we would stay pinned to the old broken version instead of moving with the vendor to the new patched version? The official documentation recommends syntax like actions/setup-python@v6 which lets the action stay "subscribed" to new security fixes.

But I'm new at this and maybe there are other docs you need to point me at. Thanks!

@neutrinoceros
Copy link
Copy Markdown
Contributor Author

But isn't pinning also a security risk, since if a bug is found in, say, actions/setup-python, and the vendor releases a new @v6 version of the action that fixes the bug, then we would stay pinned to the old broken version instead of moving with the vendor to the new patched version?

Yeah, but that's only if you never upgrade again. Dependabot works well enough for periodic upgrades at a relatively long interval now (quarterly), and it also support cooldown periods to ignore versions that are more recent than a given threshold (usually, a week), protecting you against supply chain attacks by giving plenty time to upstream maintainers to course correct in case they ever get compromised.
Happy to set that up too if you're interested.
Also for completion: the technology has been around for a while, but for the longest time, it wasn't really worth the effort of going all the way in on security measures for small projects with a limited audience/impact radius. What's changed is that attack campaigns are becoming much cheaper to run with agentic AI, so I'm spreading the word.

@brandon-rhodes
Copy link
Copy Markdown
Owner

Dependabot works well enough for periodic upgrades …

So — to see if I understand this point — Dependabot these days understands not only the notation @v6 but also @a309ff8b426b58ec0e2a45f0f869d46889d02405, and just like it's capable of saying "hey, v6 is out of date, let's tell the project maintainer", it can also recognize that the hash points at an out-of-date version, and recommend that it be bumped?

Let me think through the two possible vulnerability surfaces here. There are two dangerous situations:

Danger 1 — an existing action is discovered to be vulnerable to an exploit. Once the problem is discovered, the vendor, either GitHub or the PyPA, releases a fixed version of the action to replace the flawed version.
Danger 2 — someone compromises either GitHub Actions or the PyPA and releases a new version of an action I'm using that is deliberately exploitable. Then the problem is discovered and they release a new, fixed action (or roll back the bad release).

If my actions are specified with a version like @v6, then I'm vulnerable to both Danger 1 and Danger 2. In both cases, though, the situation automatically heals, and I'm safe again, once the vendor releases a fixed action.

If my actions are specified like @…hash…, then Danger 2 goes away. A malicious release of a new version of an action by a bad actor can no longer make my project's release logic run malicious code. But Danger 1 not only remains, but becomes much worse. If an existing action, that I pinned to and that the vendor thought was a known-good action, is discovered to be vulnerable, then even as the vendor releases a new @v6, then I miss out, and will keep running the compromised action code until some time later when Dependabot comes along and lets me know that the hash-specified action is compromised and should be abandoned.

So to decide between approaches, I need to weigh Danger 1 against Danger 2, since switching to hashes fixes one danger while making the other much worse.

It seems to me that Danger 1 is by far the more likely. Vendors discover problems in code all the time and have to release patches and fixes. But Danger 2 seems very unlikely. While there will doubtless be an occasion on which either GitHub Actions or the PyPA are compromised, and malicious code is released in their name, I would expect that to be far rarer than the case where they accidentally release code of their own that, it turns out, has a flaw.

So switching to hashes would seem much more dangerous than sticking with the advice of the official GitHub docs, and using designations like @v6?

If you could: try writing up how you think of the trade-off, using these same two "Danger" categories, or adding more if there are other ways an attack surface could arise that I'm not thinking of.

And thanks again for all the effort you're making here with sgp4! I'm learning a lot, and am grateful.

@neutrinoceros
Copy link
Copy Markdown
Contributor Author

just like it's capable of saying "hey, v6 is out of date, let's tell the project maintainer", it can also recognize that the hash points at an out-of-date version, and recommend that it be bumped?

yes. It'll open PRs on its own actually, according to a preset schedule, and only go out of schedule when and if a vulnerability is detected in your pinned versions.

But Danger 1 not only remains, but becomes much worse.

Still, only if you don't have a way to automate upgrades.

Your whole reasoning is very sound, it's just missing a crucial bit of information that I added here :)

And thanks again for all the effort you're making here with sgp4! I'm learning a lot, and am grateful.

Thanks for being so thoughtful in your reviews, I really appreciate these discussions !

@brandon-rhodes
Copy link
Copy Markdown
Owner

Alas — given the troubles I've had before with GitHub Actions, I'm not ready at this point to switch away from the @v6 notation that GitHub themselves recommend in the documentation. And I would rather keep all my projects symmetric at this point, rather than have sgp4 diverge and start behaving the opposite of the others.

But I would be happy to accept this if the upgrades switch to the simple @v6 notation, so feel free to re-submit with that tweak. Or I could tackle that myself later, if this PR was enough work already, and you'd rather close it for now; you've done so much work already for the project, and I know it's trouble to update yet another PR. Thanks again!

@neutrinoceros
Copy link
Copy Markdown
Contributor Author

It's really no trouble, but it is a different enough goal that I'd rather do it as a separate PR

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants