Implementation:Trailofbits Fickling FicklingMLUnpickler Load
| Knowledge Sources | |
|---|---|
| Domains | Security, ML_Safety, Deserialization |
| Last Updated | 2026-02-14 14:00 GMT |
Overview
Concrete tool for safe ML model deserialization with allowlist enforcement provided by the Fickling library.
Description
FicklingMLUnpickler is a subclass of pickle.Unpickler that overrides find_class to validate every import against ML_ALLOWLIST. It accepts an optional also_allow parameter for extending the allowlist at construction time. When used via the hook system, it transparently replaces standard pickle operations so that torch.load() and pickle.load() are automatically protected.
Usage
This class is typically used indirectly through activate_safe_ml_environment(). Direct usage is for cases where you need fine-grained control over which specific deserialization calls are protected.
Code Reference
Source Location
- Repository: fickling
- File: fickling/ml.py
- Lines: L340-369
Signature
class FicklingMLUnpickler(pickle.Unpickler):
def __init__(self, *args, also_allow: list[str] | None = None, **kwargs):
"""
Args:
*args: Passed to pickle.Unpickler (first arg is file-like object).
also_allow: Optional list of dotted import paths to allow
beyond ML_ALLOWLIST (e.g., ["mymodule.MyClass"]).
**kwargs: Passed to pickle.Unpickler.
"""
def find_class(self, module: str, name: str):
"""Validate import against allowlist before resolving.
Raises:
UnsafeFileError: If module or name is not in the allowlist.
"""
Import
from fickling.ml import FicklingMLUnpickler
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| file | BinaryIO | Yes | File-like object containing pickle data (first positional arg to pickle.Unpickler) |
| also_allow | list[str] or None | No | Additional dotted import paths to allow (e.g., ["mymodule.MyClass"]) |
Outputs
| Name | Type | Description |
|---|---|---|
| .load() returns | Any | The deserialized Python object if all imports pass validation |
| Exception | UnsafeFileError | Raised if any import during deserialization is not in the allowlist |
Usage Examples
Direct Usage
from fickling.ml import FicklingMLUnpickler
# Load a pickle file with ML allowlist enforcement
with open("model_weights.pkl", "rb") as f:
unpickler = FicklingMLUnpickler(f)
model_data = unpickler.load()
With Custom Allowed Imports
from fickling.ml import FicklingMLUnpickler
with open("custom_model.pkl", "rb") as f:
unpickler = FicklingMLUnpickler(
f,
also_allow=["myapp.models.CustomModel"]
)
model_data = unpickler.load()