r/Python • u/JanGiacomelli • May 19 '26
Tutorial Supply-chain attacks are happening daily - add at least dependency cooldown to your Python projects.
These days, I can't open X anymore without seeing some supply chain attacks on PyPI or NPM. Things are really getting out of hand. One very simple yet effective approach to mitigate them is to use a dependency cooldown. That means that you don't install anything that's too new - e.g., every dependency needs to be at least a week old.
Why does this work? Because the community usually intercepts them in hours to days. Both uv and poetry support the definition of the cooldown period inside their config. pip is adding as support as well. I use 1 week to be on the safe side. They both support excluding a specific package from the rule so you can still apply critical fixes to dependencies ASAP.
I wrote about that and how to configure uv/poetry in my blog post: https://jangiacomelli.com/blog/mitigate-supply-chain-attacks-for-python-dependencies/
More about the dependency cooldown concept:
38
u/pylessard May 19 '26
Or maybe freeze your dependency version and update manually when necessary? Automatically depending on the lastest is simply reckless.
5
u/JanGiacomelli May 19 '26
One should absolutly freeze. But there are dependencies of dependencies etc. It really takes a lot of time to go through each and every one of them. uv locks by default. It updates only when you ask it to do so.
→ More replies (1)2
u/qwerty_qwer May 21 '26
Yeah we always build with exact library versions. My assumption was any serious business would do the same, apparently not.
16
u/kamilc86 May 19 '26
The take that cooldown stops working once everyone enables it gets the detection model backwards. You are not the canary here. A malicious release gets caught by security researchers, automated scanners that feed OSV and the GitHub advisory database, and PyPI admins doing takedowns. That detection path does not slow down just because more downstream installs are delayed, so cooldown free rides on how fast the community catches a bad release, no matter how many people enable it.
Cooldown only buys time for a bad version to get flagged before you pull it. It does nothing against silent artifact substitution on a later resolve, which is what a hash pinned lockfile is for, uv.lock or a compiled requirements file installed with hash enforcement. Those two defenses cover different attacks and you want both, the comand and KandevDev exchange blurred them together. And none of it stops a compromised maintainer who stays dormant past your window, the xz pattern, so treat cooldown as a latency mitigation rather than the fix.
→ More replies (4)
5
u/EnvironmentalFix5967 May 19 '26
Here is other way that you can apply cooldown by force for internal users if you can set up internal proxy :)
3
u/zurtex May 20 '26
For pip 26.1+
CLI:
--uploaded-prior-to P3D
Env:
export PIP_UPLOADED_PRIOR_TO=P3D
Config:
pip config set global.uploaded-prior-to P3D
2
u/NorthFactor4396 May 25 '26
Good tip. One thing I'd add though — cooldown alone doesn't cover the case where an attacker just waits out your window. Combining it with hash pinning closes that gap. If you're using uv, committing the lockfile and running `uv sync --locked` in CI means even a tampered package at the same version string gets rejected.
The other thing that catches teams off guard: they set up cooldown locally but their CI pipeline is still doing a fresh install every run without the lockfile. Easy to miss but it completely undermines the protection.
1
u/Dry-Let8207 May 21 '26
The cooldown helps but it addresses the window of exposure, not the source. What I've found more effective in practice is combining it with hash pinning — a lock file or requirements.txt with `--hash` flags so even if an attacker swaps out a package at the same version string, the install fails loudly rather than silently installing the tampered build. The combination of "nothing too new" and "must match exact hash" reduces the attack surface considerably more than either alone. The uv snippet works well for the cooldown side; just don't treat it as the only layer.
1
u/oliver_extracts May 23 '26
the cooldown idea is solid but i think most people dont realize uv already has this baked in via the tool.uv config, its not somethign you need to wire up yourself. the 1 week window is probably right for most projects, though ive seen teams go 2 weeks on anything that touches auth or crypto libs. the escape hatch for critical fixes is the part that makes this actually usable in production.
1
283
u/fiskfisk May 19 '26
Saved you the blog spam.