tsshare — a Tushare-impersonating PyPI client that hides its endpoint in base64 and exfiltrates your API token and a hardware fingerprint
The PyPI package tsshare poses as a client “compatible with Tushare pro_bar” but conceals its real backend: client.py base64-decodes a string to the hardcoded raw IP https://47.112.191.75 (Alibaba Cloud, China). On every API call it builds a persistent hardware fingerprint and forwards the user's Tushare API token to that hidden endpoint. All eight published versions are affected.
tsshare is published to PyPI as a market-data client and advertises itself, in its own docstrings, as “通用行情接口,兼容 Tushare pro_bar” (a general market-data interface compatible with Tushare pro_bar). It even ships backward-compat aliases MyShareClient / MyShareError. The name is confusable with the widely-used legitimate library Tushare — this is an impersonation.
The endpoint is deliberately hidden. Rather than pointing at a named API domain, tsshare/client.py stores its default base URL base64-encoded and decodes it at runtime: _b64.b64decode(b"aHR0cHM6Ly80Ny4xMTIuMTkxLjc1") → https://47.112.191.75 — a hardcoded raw IP in Alibaba Cloud's China range (the same 47.112.x block seen in other China-hosted telemetry abuse). Legitimate clients do not base64-encode their own base URL; the only purpose of that encoding is to keep the endpoint out of plain sight of a casual reader or a simple string scan.
What it sends. When the user calls the API, the client first builds a persistent, cross-platform hardware fingerprint — on Windows the disk-drive serial number via PowerShell Get-CimInstance Win32_DiskDrive, on macOS the Hardware UUID via system_profiler, on Linux the contents of /etc/machine-id. It then routes the request — carrying the user's Tushare auth_code token — to the hidden raw-IP endpoint. The operator therefore receives the user's paid API token together with a stable machine identifier that survives reinstalls.
No install-time hook. There is no malicious setup.py / postinstall; the package imports cleanly and does nothing on install. The exfiltration happens on API use — which is precisely why an install-time scanner, or a reviewer who only checks the install path, would wave it through.
tsshare did not come from a targeted hunt — it surfaced during a systematic cross-check of the open pull requests in the OSSF malicious-packages feed against our own scan corpus. The goal of that pass was to find packages the community was flagging that we had data on but had not yet triaged.
tsshare was one of them: it was sitting un-triaged in our PyPI backlog even though our scanners had already flagged two high-signal indicators on client.py — a mosaic.assembled-url (a URL assembled/obfuscated at runtime) and a recon-beacon (host/environment fingerprinting). Those two hits on a tiny, obscure package were enough to justify a manual look.
We then did a flag-safe static review of the published sdists — reading the source only, no execution, no live callback. That confirmed the full dataflow at the indicator level: the base64 string decodes to the raw IP, the fingerprint functions collect stable machine identifiers, and the user's auth_code is routed to the hidden endpoint. We verified the earliest version in our corpus (1.0.5) already contains the identical hidden endpoint and fingerprinting, which is what lets us say the package was malicious from the start rather than compromised later.
All eight versions present in our corpus are affected: 1.0.5, 1.0.6, 1.0.9, 1.0.14, 1.0.15, 1.0.16, 1.0.18, 1.0.19. The hidden endpoint and the fingerprinting are present in the earliest version we hold (1.0.5), so the entire package is treated as malicious (introduced: 0).
tsshare versions 1.0.5 → 1.0.19 published to PyPI, each carrying the hidden endpoint + fingerprinting.https://47.112.191.75tsshare/client.py: _b64.b64decode(b"aHR0cHM6Ly80Ny4xMTIuMTkxLjc1") → the raw IP aboveWin32_DiskDrive serial · macOS Hardware UUID · Linux /etc/machine-idauth_code token + the machine fingerprint, sent to the hidden endpointMyShareClient / MyShareError (confusable with the legitimate tushare)tsshare/client.pyVerified by static code + dataflow review of the published PyPI sdists; no execution, no live callback. Surfaced during an OSSF malicious-packages open-PR cross-check against the codelake corpus.