Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Heuristic:Trailofbits Fickling Injection Mode Selection

From Leeroopedia
Knowledge Sources
Domains Security, Security_Research
Last Updated 2026-02-14 13:00 GMT

Overview

Decision framework for choosing between insertion and combination injection modes when injecting payloads into PyTorch model files for security research.

Description

Fickling's `PyTorchModelWrapper.inject_payload()` supports two injection modes that differ in how the payload interacts with the original model data. The choice of mode determines whether the injected payload can bypass weight-based unpicklers and whether the original model functionality is preserved.

Usage

Use this heuristic when performing security research or red team exercises that require injecting code into PyTorch model files. The injection mode determines the attack surface and detection profile of the resulting payload.

The Insight (Rule of Thumb)

  • Insertion mode (`injection="insertion"`):
    • Action: Injects Python execution opcodes directly into the existing `data.pkl` within the ZIP archive.
    • Trade-off: Does NOT bypass weight-based unpicklers (e.g., PyTorch's `weights_only=True`). The original pickle structure is modified in-place.
    • Best for: Testing static analysis tools like fickling itself; the injection is visible at the pickle opcode level.
  • Combination mode (`injection="combination"`):
    • Action: Wraps the original model in a `BaseInjection` class whose `__reduce__` returns `eval(payload)`, then saves with `torch.save()`.
    • Trade-off: Creates a completely new pickle structure. The original model becomes a nested attribute. Requires PyTorch to create.
    • Best for: Testing `torch.load()` consumers that do not use `weights_only=True`; the payload executes via `__reduce__`.
  • Default: Use `injection="all"` is not a valid option; choose one explicitly.

Reasoning

The two modes target different points in the deserialization pipeline:

Insertion modifies the pickle bytecode directly by calling `pickled.insert_python_exec(payload)`. This adds opcodes to the existing stream. A weights-based unpickler that only allows tensor reconstruction functions will reject these extra opcodes.

Combination creates an entirely new model object (`BaseInjection`) that wraps the original model. The `__reduce__` method returns `(eval, (payload,))`, so the payload runs when the object is reconstructed. This exploits the fundamental pickle deserialization mechanism rather than injecting extra opcodes.

Code evidence from `fickling/pytorch.py:134-151`:

if injection == "insertion":
    # This does NOT bypass the weights based unpickler
    pickled = self.pickled
    pickled.insert_python_exec(payload)
    # Create a new ZIP file to store the modified data
    with zipfile.ZipFile(output_path, "w") as new_zip_ref:
        with zipfile.ZipFile(self.path, "r") as zip_ref:
            for item in zip_ref.infolist():
                with zip_ref.open(item.filename) as entry:
                    if item.filename.endswith("/data.pkl"):
                        new_zip_ref.writestr(item.filename, pickled.dumps())
                    else:
                        new_zip_ref.writestr(item.filename, entry.read())
if injection == "combination":
    injected_model = BaseInjection(self.pickled, payload)
    torch.save(injected_model, output_path)

The inline comment `# This does NOT bypass the weights based unpickler` is critical tribal knowledge that is not documented anywhere else.

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment