PT-2026-25526 · Pypi · Fickling
Publicado
2026-03-04
·
Atualizado
2026-03-04
CVSS v4.0
8.9
Alta
| Vetor | AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:P |
Assessment
The missing pickle entrypoints
pickle.loads, pickle.loads, and pickle.load were added to the hook https://github.com/trailofbits/fickling/commit/8c24c6edabceab156cfd41f4d70b650e1cdad1f7.Original report
Summary
fickling.always check safety() does not hook all pickle entry points. pickle.loads, pickle.loads, and pickle.load remain unprotected, enabling malicious payload execution despite global safety mode being enabled.Affected versions
<= 0.1.8 (verified on current upstream HEAD as of 2026-03-03)Non-duplication check against published Fickling GHSAs
No published advisory covers hook-coverage bypass in
run hook().
Existing advisories are blocklist/detection bypasses (runpy, pty, cProfile, marshal/types, builtins, network constructors, OBJ visibility, etc.), not runtime hook coverage parity.Root cause
run hook() patches only:pickle.loadpickle.Unpicklerpickle.Unpickler
It does not patch:
pickle.loadspickle.loadpickle.loads
Reproduction (clean upstream)
python
import io, pickle, pickle
from unittest.mock import patch
import fickling
from fickling.exception import UnsafeFileError
class Payload:
def reduce (self):
import subprocess
return (subprocess.Popen, (['echo','BYPASS'],))
data = pickle.dumps(Payload())
fickling.always check safety()
# Bypass path
with patch('subprocess.Popen') as popen mock:
pickle.loads(data)
print('bypass sink called?', popen mock.called) # True
# Control path is blocked
with patch('subprocess.Popen') as popen mock:
try:
pickle.load(io.BytesIO(data))
except UnsafeFileError:
pass
print('blocked sink called?', popen mock.called) # FalseObserved on vulnerable code:
pickle.loadsexecutes payloadpickle.loadis blocked
Minimal patch diff
diff
--- a/fickling/hook.py
+++ b/fickling/hook.py
@@
def run hook():
- pickle.load = loader.load
+ pickle.load = loader.load
+ pickle.load = loader.load
+ pickle.loads = loader.loads
+ pickle.loads = loader.loadsValidation after patch
pickle.loads,pickle.loads, andpickle.loadall raiseUnsafeFileError- sink not called in any path
Regression tests added locally:
test run hook blocks pickle loadstest run hook blocks pickle load and loadsintest/test security regressions 20260303.py
Impact
High-confidence runtime protection bypass for applications that trust
always check safety() as global guard.Correção
Protection Mechanism Failure
Encontrou algum problema na descrição? Tem algo a acrescentar? Fique à vontade para nos escrever 👾
Enumeração de Fraquezas
Identificadores relacionados
Produtos afetados
Fickling