A blog post about the quite serious security implications of FODs, and our mitigation.
The other very simple fix here is that we stop naming all FOD derivations source but derive the fod derivation name from the package name and version. This stops cross package contamination of FODs
There’s a PR for this in nixpkgs that solves this. Though I’m having trouble finding it right now.,
See also:
Also some discussion that lead to the ca-derivation-based idea here:
I wish that there existed an option to toggle this behaviour in nix.conf(5).
Oh we hadn’t seen that discussion before (we thought we were the first to suggest that idea
).
Is the idea then to also have globally unique names somehow? Otherwise, can’t I create a Haskell package called gcc, with version 14.3.0, and still pull off the attack?
EDIT: or is this specifically for fetchers that have hash versioning (like git), as suggested here?
But it’s not behavior of nix. It’s pure nixpkgs decision how to name the derivations.
Maybe we can add a FOD check github action in the Nixpkgs repo to automatically verify all changed FOD in a new PR (when it is not a mass rebuild)?
Actually, since ofborg building often stucks for a long time is there any plan to migrate it to github actions in the future (just like evals are now handled by gh)?
Thank you so much for that writeup. Reading it helped, as before I had difficulties to connect the dots on how what you describe as the attack would actually deploy, again very comprehensive, actionable information.
Yeah, I also created this CVE NVD - CVE-2024-36050 after describing this exact attack here Provide a binary cache for builds · Issue #68 · NixOS/ofborg · GitHub and to the security team a while ago.
I also proposed there and around some fixes, but forcing the name of a derivation instead of source is not a good solution.
Using different names might be useful for the non-malicious scenarios, which is how it got proposed at least a couple times in the past.
Using different names forces a full rebuild when you switch the source for exactly the same data, though.
Unless it’s a CA derivation.
I don’t think the case of “switching from fetchFromGitHub to fetchgit with the exact same result but not being able to pay the cost of another download/build” is very common/compelling, to be honest. We cause rebuilds for far sillier things than that in practice.
I don’t think that encoding more in the names of FODs would solve the fundamental security issue here, but it would at least make the exploit conditions meaningfully harder to achieve, as well as fixing the incredibly common and annoying UX issue of changing the version but not the hash without getting an error. I am in favour of landing Make `fetch*` source derivation names (optionally) more descriptive and homogenize them across fetchers by oxij · Pull Request #49862 · NixOS/nixpkgs · GitHub and adjusting the default. I have a feeling that the only reason we haven’t done it is because nobody feels like being the one to make the call (though of course it ought not be done in this particular current stage of the release cycle).
I don’t buy this argument. Nixpkgs is too huge to ensure that there is not a single packet that is abusing (or will abuse) the name attribute. But I agree about the fact that it helps for honest scenario where you change a version and forget to update the hash, just this is not a security feature.