{"id":"MAL-2026-16044","kind":"package","aliases":["MAL-2026-16044"],"related":[],"title":"Malicious code in tsshare (PyPI)","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.\n\n---\n_-= Per source details. Do not edit below this line.=-_\n\n## Source: amazon-inspector (539c8fdb69887b093801655215f1857f53abb20e6dc763198c543def86c39387)\nThe 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.","summary":null,"severity":"critical","cvss":null,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"tsshare","fixed":[],"affected":"all versions","ecosystem":"pypi"}],"ecosystems":["pypi"],"tags":["malicious","package"],"not_affected_if":[],"how_to_check":null,"fix":null,"status":"open","published_at":"2026-09-04T00:00:00+00:00","first_seen_at":"2026-10-26T20:51:58+00:00","triaged_at":"2026-10-26T21:12:36+00:00","updated_at":"2026-10-26T21:12:36+00:00","category":"package","confidence":null,"triage":null,"analyst_status":null,"analyst_note":null,"search":"'-16044':8A,11A '-2026':7A,10A '-256':319C '/.tsshare/device_id.json':325C '/api/v1/proxy':199C '/etc/machine-id':109C,315C '1.0.18':60C '1.0.19':75C '1.0.5':59C '47.112.191.75':69C,198C,287C '539c8fdb69887b093801655215f1857f53abb20e6dc763198c543def86c39387':165C 'advertis':33C,348C 'ahr0chm6ly80ny4xmtiumtkxljc1':214C 'alias':44C 'alibaba':70C 'also':290C 'amazon':163C 'amazon-inspector':162C 'api':49C,132C,150C,180C 'attach':327C 'auth':119C,243C,251C,376C 'b':213C 'backend':196C,337C 'bar':38C 'bare':228C,386C 'bare-ip':385C 'base':221C 'base64':53C,210C 'base64-decoding':52C 'base64-encoded':209C 'bodi':258C 'boundari':272C 'build':86C 'cach':322C 'call':184C,249C 'caller':240C 'carri':114C 'cert':391C 'certif':352C 'china':72C 'chines':25C 'client':85C,289C 'cloud':71C 'code':2A,120C,244C,252C,254C,377C 'collect':291C 'compat':34C 'conceal':46C 'credenti':233C,268C 'cross':90C 'cross-platform':89C 'data':28C 'decod':54C,63C,216C 'default':48C,195C,220C,360C,362C 'destin':205C,225C 'detail':154C 'disabl':358C 'disk':96C 'disk-driv':95C 'diskdriv':101C,305C 'dispatch':186C 'docstr':32C 'domain':80C 'drive':97C 'drop':173C 'drop-in':172C 'e':212C 'edit':157C 'encod':211C 'endpoint':50C,125C,261C,389C 'everi':182C,246C,333C 'exfiltr':147C 'fals':364C 'fingerprint':93C,295C 'first':297C 'fszzw56.com':81C 'function':350C 'give':335C 'hardcod':66C,194C 'hardwar':92C,103C,294C,311C,379C 'hash':320C 'hidden':124C 'hook':146C 'https':388C 'id':331C,380C 'identifi':139C,344C 'imperson':22C 'includ':250C 'insecurerequestwarn':371C 'inspector':164C 'instal':144C 'install-tim':143C 'ip':68C,229C,387C 'issu':275C 'issuer':235C 'leav':269C 'librari':29C 'line':160C 'linux':108C,317C 'log':280C 'machin':138C,343C 'maco':102C,314C 'mal':6A,9A 'malici':1A,13B,20C 'market':27C 'market-data':26C 'meta.device':330C 'method':183C 'mysharecli':42C 'myshareerror':43C 'occur':148C 'oper':128C,285C,338C 'packag':14B,17C,167C 'paid':131C,264C 'parti':267C 'per':152C,342C 'per-machin':341C 'persist':88C,293C 'platform':91C 'popular':24C 'post':191C,257C 'powershel':299C 'present':168C 'pro':37C,179C 'processor':301C 'processorid':302C 'profil':107C,310C 'proxi':248C,349C 'pypi':5A,16C 'queri':189C 'rather':200C 'raw':67C 'receiv':129C 'replac':175C 'replay':282C 'request':113C,334C 'requests.session':356C 'rotat':77C 'rout':111C 'runtim':57C,218C 'self.auth':253C 'serial':98C 'serialnumb':306C 'session.verify':361C 'set':236C 'sha':318C 'ship':41C 'silenc':373C 'sourc':153C,161C 'ssl':367C 'stabl':137C,340C 'store':208C,238C 'subsequ':247C 'system':106C,309C 'third':266C 'third-parti':265C 'time':145C 'tls':351C 'togeth':134C 'token':121C,133C,237C 'transmit':382C 'trust':271C 'tsshare':4A,12A,18C,366C 'tsshare/client.py':45C 'tushar':30C,36C,118C,177C,242C 'tushare.pro':203C 'unnecessari':345C 'unrel':230C 'url':206C,222C 'urllib3':370C 'use':83C,151C,298C 'user':116C 'uuid':104C,312C 'valid':392C 'valu':62C 'verif':353C 'verify/myshare_ssl_verify':368C 'via':99C,105C,365C 'win32':100C,300C,304C 'window':94C,308C 'without':390C","nicknames":[],"mitigations":[],"who_affected":null,"tier":null,"verified":{},"analyst_revisit_at":null,"first_public_at":"2026-09-04T00:00:00+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"osv-malicious","external_id":"MAL-2026-16044","url":"https://osv.dev/vulnerability/MAL-2026-16044","severity":"critical","published_at":"2026-09-04T00:00:00+00:00","modified_at":"2026-09-23T05:00:10+00:00","first_seen_at":"2026-10-26T20:51:58+00:00","fetched_at":"2026-10-26T20:51:58+00:00","note":null}],"documents":[],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}