
Ein Python-Pickling-Decompiler und statischer Analysator

Fickling ist ein Decompiler, statischer Analyzer und Bytecode-Rewriter für Python-pickle-Objektserialisierungen. Du kannst fickling verwenden, um bösartige pickle- oder pickle-basierte Dateien – einschließlich PyTorch-Dateien – zu erkennen, zu analysieren, zurückzuentwickeln oder sogar zu erstellen.
Fickling kann sowohl als Python-Bibliothek als auch als CLI verwendet werden.
Fickling erfordert Python 3.11 oder neuer und hat nur sehr wenige Abhängigkeiten. Sowohl die Bibliothek als auch das Kommandozeilenwerkzeug können über pip oder uv installiert werden:
# Using pip
python -m pip install fickling
# Using uv
uv pip install fickling
PyTorch ist eine optionale Abhängigkeit von Fickling. Um daher Ficklings pytorch- und polyglot-Module zu verwenden, sollten Sie Folgendes ausführen:
# Using pip
python -m pip install fickling[torch]
# Using uv
uv pip install fickling[torch]
Fickling kann dabei helfen, KI/ML-Codebasen abzusichern, indem es automatisch Pickle-Dateien scannt, die in Modellen enthalten sind. Fickling hakt sich in das pickle-Modul ein und überprüft die Imports, die beim Laden eines Modells ausgeführt werden. Es prüft die Imports ausschließlich gegen eine Allowlist von Imports aus ML-Bibliotheken, die als sicher gelten, und blockiert Dateien, die andere Imports enthalten.
Fügen Sie die folgenden Zeilen so früh wie möglich hinzu, bevor Sie torch, numpy oder eine andere Bibliothek importieren, die pickle verwendet:
import fickling
# This sets global hooks on pickle
fickling.hook.activate_safe_ml_environment()
Zum Entfernen des Schutzes:
fickling.hook.deactivate_safe_ml_environment()
Es ist möglich, dass die von Ihnen verwendeten Modelle Imports enthalten, die von Fickling nicht erlaubt sind. Wenn Sie das Modell dennoch laden möchten, können Sie einfach zusätzliche Imports für Ihren spezifischen Anwendungsfall mit dem Argument also_allow erlauben:
fickling.hook.activate_safe_ml_environment(
also_allow=[
"some.import",
"another.allowed.import",
]
)
Wichtig: Sie sollten stets sicherstellen, dass manuell hinzugefügte Importe tatsächlich sicher sind und Angreifern nicht die Ausführung beliebigen Codes ermöglichen. Wenn Sie unsicher sind, wie Sie dies bewerkstelligen sollen, können Sie ein Issue im GitHub-Repository von Fickling eröffnen, das die betreffenden Importe/Modelle angibt, und unser Team kann diese überprüfen und sie nach Möglichkeit in die Allow-List aufnehmen.
Fickling kann nahtlos in Ihre Codebasis integriert werden, um das Laden bösartiger Dateien zur Laufzeit zu erkennen und zu unterbinden.
Im Folgenden zeigen wir die verschiedenen Möglichkeiten, wie Sie fickling verwenden können, um Sicherheitsprüfungen für Pickle-Dateien zu erzwingen. Im Hintergrund hakt es sich in die pickle-Bibliothek ein, um Sicherheitsprüfungen hinzuzufügen, sodass das Laden einer Pickle-Datei eine UnsafeFileError-Ausnahme auslöst, wenn in der Datei bösartiger Inhalt erkannt wird.
# This enforces safety checks every time pickle is used to deserialize
fickling.always_check_safety()
# Attempt to load an unsafe file now raises an exception
with open("file.pkl", "rb") as f:
try:
pickle.load(f)
except fickling.UnsafeFileError:
print("Unsafe file!")
with fickling.check_safety():
# All pickle files loaded within the context manager are checked for safety
try:
with open("file.pkl", "rb") as f:
pickle.load("file.pkl")
except fickling.UnsafeFileError:
print("Unsafe file!")
# Files loaded outside of context manager are NOT checked
pickle.load("file.pkl")
Beim Verlassen stellt der Context-Manager den Zustand wieder her, der beim Eintritt installiert war, sodass ein bereits vorhandener Hook wirksam bleibt, statt dass pickle ungeschützt zurückbleibt.
# Use fickling.load() in place of pickle.load() to check safety and load a single pickle file
try:
fickling.load("file.pkl")
except fickling.UnsafeFileError as e:
print("Unsafe file!")
# Perform a safety check on a pickle file without loading it
if not fickling.is_likely_safe("file.pkl"):
print("Unsafe file!")
Sie können auf die Details der Sicherheitsanalyse von fickling innerhalb der ausgelösten Ausnahme zugreifen:
>>> try:
... fickling.load("unsafe.pkl")
... except fickling.UnsafeFileError as e:
... print(e.info)
{
"severity": "OVERTLY_MALICIOUS",
"analysis": "Call to `eval(b'[5, 6, 7, 8]')` is almost certainly evidence of a malicious pickle file. Variable `_var0` is assigned value `eval(b'[5, 6, 7, 8]')` but unused afterward; this is suspicious and indicative of a malicious pickle file",
"detailed_results": {
"AnalysisResult": {
"OvertlyBadEval": "eval(b'[5, 6, 7, 8]')",
"UnusedVariables": [
"_var0",
"eval(b'[5, 6, 7, 8]')"
]
}
}
}
Wenn Sie eine andere Sprache als Python verwenden, können Sie weiterhin ficklings CLI verwenden, um Pickle-Dateien auf Sicherheit zu prüfen:
fickling --check-safety -p pickled.data
Ficklings CLI ermöglicht es, die Ausführung der Pickle-Virtual-Machine sicher zu verfolgen, ohne
bösartigen Code auszuführen:
fickling --trace file.pkl
Fickling ermöglicht es, beliebigen Code in eine Pickle-Datei einzuschleusen, der jedes Mal ausgeführt wird, wenn die Datei geladen wird
fickling --inject "print('Malicious')" file.pkl > malicious.pkl
Fickling kann verwendet werden, um eine Pickle-Datei zur weiteren Analyse zu dekompilieren
>>> import ast, pickle
>>> from fickling.fickle import Pickled
>>> fickled_object = Pickled.load(pickle.dumps([1, 2, 3, 4]))
>>> print(ast.dump(fickled_object.ast, indent=4))
Module(
body=[
Assign(
targets=[
Name(id='result', ctx=Store())],
value=List(
elts=[
Constant(value=1),
Constant(value=2),
Constant(value=3),
Constant(value=4)],
ctx=Load()))],
type_ignores=[])
PyTorch enthält mehrere Dateiformate, mit denen sich Polyglot-Dateien erstellen lassen, also Dateien, die gültig als mehr als ein Dateiformat interpretiert werden können. Fickling unterstützt das Identifizieren, Inspizieren und Erstellen von Polyglots mit den folgenden PyTorch-Dateiformaten: