Mitigate supply-chain attacks for Python dependencies
May 18, 2026
Week after week, we see supply-chain attacks. From LiteLLM to axios. Just last week, there was a tanstack.
🚨 UPDATE: Mini Shai-Hulud has crossed from @npmjs into @pypi and is still spreading.
— Socket (@SocketSecurity) May 12, 2026
Newly confirmed compromised artifacts:
@opensearch-project/opensearch: 3.5.3, 3.6.2, 3.7.0, 3.8.0 (1.3M weekly downloads)
mistralai: 2.4.6 on PyPI
guardrails-ai: 0.10.1 on PyPI
additional… pic.twitter.com/iyTuSFGdAU
We see them more and more often.
Yet, quite often, we add dependencies to our projects without thinking twice. uv add httpx and we move on.
But every dependency is code written by someone else. Code that gets executed in your application, in your CI/CD pipeline, on your production server.
Supply chain attacks exploit exactly that trust. A compromised package gets published, and anyone who installs it immediately is exposed.
Well-known libraries are no exception there. Anyone can be a victim of social engineering.
And attackers are targeting popular libraries to reach the largest number of victims.
So the question is: how do we mitigate that?
Simplest mitigation of supply chain attacks - dependency cooldowns
There are various approaches to this. As suggested by Gergely Orosz, we can mitigate the issue by doing one or more of the following things:
- Use fewer dependencies
- Write our own dependencies
- Self-host our package registry
Supply chain attacks are happening left and right with npm, PyPI, and so many other places. It seems to be getting worse, everyone agrees.
— Gergely Orosz (@GergelyOrosz) May 12, 2026
But what can you do about it?
Some thoughts on possible approaches (all have tradeoffs).
What did I miss? And what vendors actually work? pic.twitter.com/Akh0xUARZV
The last one is usually out of the question - unless you have a large team. The first two are great approaches in general. One should really think it through before installing a dependency. Is it really needed? Many dependencies are very easy to recreate, so the cost of implementing them ourselves might be much lower than the risk of an exploit via supply chain attack. That's not true for every dependency. For example, rewriting Django, FastAPI or Pydantic AI from scratch might pose a bigger risk than installing them. So what are the other options?
One approach is dependency cooldown. It was William Woodruff who coined the term dependency cooldowns. The idea is simple: don't install freshly published packages. Wait. Let the community catch the bad ones before they reach your lock file. This isn't theoretical caution. It's empirically effective against the majority of high-visibility, mass-impact supply chain attacks. As per William's blog, most of the attacks are caught within hours to days. Given the latest attacks, a 1-week grace period seems like a good choice.
You can read Simon Willison's blog post for more info about the dependency cooldowns
Dependency cooldown with Python package managers
It's a hot topic, and many package managers are adding support for dependency cooldowns.
uv and poetry both support it via configuration.
pip added support as a CLI flag --uploaded-prior-to in version 26.1.
Since support for uv and poetry is the best, let's focus on them.
uv
If you're using uv, you can enforce a cooldown with two lines in pyproject.toml:
[tool.uv]
exclude-newer = "1 week"
This tells uv to ignore any package version published less than 1 week ago. When you run uv lock or uv add, it simply won't see anything newer.
The workflow is straightforward:
1. Set exclude-newer to 1 week.
2. Develop as usual. You'll get the latest packages that have survived a week in the wild.
poetry
Like uv, poetry lets you specify how many days must pass since the release before dependencies are picked up.
The setting lives in poetry.toml (not pyproject.toml):
[solver]
min-release-age = 7
You can also set it via the CLI:
poetry config --local solver.min-release-age 7
This tells Poetry to ignore any package version where all distribution files are less than 7 days old.
Note: This feature requires Poetry 2.4.0 or later. It only works for package sources that expose file upload timestamps.
What about critical security patches?
Fair question. If a critical CVE fix was published 3 days ago, it won't be automatically picked up by uv.
In such a situation, you can use overrides.
uv
With uv, you can opt for a specific dependency out of the cooldown by listing it inside the exclude-newer-package table:
[tool.uv]
exclude-newer-package = {my-package = false}
This will ignore the "1 week" rule for my-package.
We should make sure to remove the override once it's not applicable anymore!
You can also be explicit about pre-releases:
[tool.uv]
exclude-newer = "1 week"
prerelease = "if-necessary-or-explicit"
prerelease = "if-necessary-or-explicit" means uv will only use prerelease versions if there's no stable version available or if you explicitly asked for one.
No accidental alpha versions sneaking into your lock file.
poetry
Like uv, poetry also offers exclusion. You define which dependencies to exclude from the cooldown rule in poetry.toml:
[solver]
min-release-age = 7
min-release-age-exclude = "my-package,other-package"
You can also exclude entire package sources (e.g., a private registry):
[solver]
min-release-age = 7
min-release-age-exclude-source = "private-repo"
Conclusion
Most of the supply chain attacks rely on speed.
Publish something malicious, hope people install it before anyone notices.
A one-week cooldown breaks that model with almost zero effort.
That doesn't mean you shouldn't apply other precautions.
You absolutely should.
But two lines in pyproject.toml can help you eliminate a whole class of risk.
Safe engineering!