tsshare (PyPI) · Malicious Code
Affects tsshareSource GCVE Database
Malicious package : remove tsshare and rotate any secrets on hosts that installed it.
Data as of 26 Oct 2026, 16:19 UTC
Malicious package
Published to PyPI · OSV MAL-2026-16044
What to do
Remove tsshare from every project, lockfile and image that pulls it in. Treat any host that installed it as compromised: rotate the credentials, tokens and keys it could read, from a clean machine.
Affected software
| Product | Affected | Fixed in |
|---|---|---|
| PyPItsshare | Affected
| Fixed in– |
Check your own hosts for these packages with threat-finder (opens in a new tab), our free open-source scanner.
Description
The PyPI package `tsshare` is malicious. It impersonates the popular Chinese market-data library `tushare` — its docstrings advertise compatibility with `Tushare pro_bar` and it ships `MyShareClient`/`MyShareError` aliases. `tsshare/client.py` conceals its default API endpoint by base64-decoding it at runtime: in 1.0.5–1.0.18 the value decodes to the hardcoded raw IP `https://47.112.191.75` (Alibaba Cloud, China), and in 1.0.19 it rotates to the domain `https://fszzw56.com`. On use, the client builds a persistent cross-platform hardware fingerprint (Windows disk-drive serial via `Win32_DiskDrive`, macOS `Hardware UUID` via `system_profiler`, Linux `/etc/machine-id`) and routes the request — carrying the user's Tushare `auth_code` token — to that hidden endpoint, so the operator receives the paid API token together with a stable machine identifier. There is no install-time hook; exfiltration occurs on API use. --- _-= Per source details. Do not edit below this line.=-_ ## Source: amazon-inspector (539c8fdb69887b093801655215f1857f53abb20e6dc763198c543def86c39387) The package presents itself as a drop-in replacement for Tushare's pro_api, but every method call is dispatched through a query() that POSTs to a hardcoded default backend at https://47.112.191.75/api/v1/proxy rather than to tushare.pro. The destination URL is stored base64-encoded (_E = b"aHR0cHM6Ly80Ny4xMTIuMTkxLjc1") and decoded at runtime by _default_base_url, and the destination is a bare IP unrelated to the credential's issuer. set_token() stores the caller's Tushare auth_code, and every subsequent proxied call includes {'auth_code': self.auth_code,...} in the POST body to that endpoint, so the paid third-party credential leaves the trust boundary it was issued for and can be logged or replayed by the operator of 47.112.191.75. The client also collects a persistent hardware fingerprint on first use — PowerShell Win32_Processor ProcessorId and Win32_DiskDrive SerialNumber on Windows, system_profiler Hardware UUID on macOS, /etc/machine-id on Linux — SHA-256 hashes it, caches it under ~/.tsshare/device_id.json, and attaches it as meta.device_id to every request, giving the backend operator a stable per-machine identifier unnecessary for the advertised proxy function. TLS certificate verification on the requests.Session is disabled by default (session.verify defaults to false via TSSHARE_SSL_VERIFY/MYSHARE_SSL_VERIFY) and urllib3 InsecureRequestWarning is silenced, so the auth_code and hardware ID are transmitted to the bare-IP HTTPS endpoint without cert validation.
References
- research.codelake.dev/advisories/clr-2026-3053-tsshare (opens in a new tab)
- pypi.org/project/tsshare/1.0.7/ (opens in a new tab)
- pypi.org/project/tsshare/1.0.5/ (opens in a new tab)
- pypi.org/project/tsshare/1.0.11/ (opens in a new tab)
- pypi.org/project/tsshare/1.0.18/ (opens in a new tab)
- pypi.org/project/tsshare/1.0.6/ (opens in a new tab)
- pypi.org/project/tsshare/1.0.14/ (opens in a new tab)
- pypi.org/project/tsshare/1.0.10/ (opens in a new tab)
- pypi.org/project/tsshare/1.0.16/ (opens in a new tab)
- pypi.org/project/tsshare/1.0.2/ (opens in a new tab)
- pypi.org/project/tsshare/1.0.8/ (opens in a new tab)
- pypi.org/project/tsshare/1.0.1/ (opens in a new tab)
- pypi.org/project/tsshare/1.0.4/ (opens in a new tab)
- pypi.org/project/tsshare/1.0.15/ (opens in a new tab)
- pypi.org/project/tsshare/1.0.17/ (opens in a new tab)
- pypi.org/project/tsshare/1.0.9/ (opens in a new tab)
- pypi.org/project/tsshare/1.0.3/ (opens in a new tab)
- pypi.org/project/tsshare/1.0.13/ (opens in a new tab)
- pypi.org/project/tsshare/1.0.12/ (opens in a new tab)
- pypi.org/project/tsshare/1.0.0/ (opens in a new tab)