VYPR
Low severityNVD Advisory· Published Apr 10, 2024· Updated Aug 1, 2024

Arbitrary Code Execution via Deserialization in huggingface/transformers

CVE-2024-3568

Description

The huggingface/transformers library is vulnerable to arbitrary code execution through deserialization of untrusted data within the load_repo_checkpoint() function of the TFPreTrainedModel() class. Attackers can execute arbitrary code and commands by crafting a malicious serialized payload, exploiting the use of pickle.load() on data from potentially untrusted sources. This vulnerability allows for remote code execution (RCE) by deceiving victims into loading a seemingly harmless checkpoint during a normal training process, thereby enabling attackers to execute arbitrary code on the targeted machine.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

CVE-2024-3568: Remote code execution through insecure pickle deserialization in Hugging Face Transformers' load_repo_checkpoint().

Root

Cause

The vulnerability resides in the load_repo_checkpoint() function of the TFPreTrainedModel() class within the Hugging Face Transformers library. This function uses pickle.load() to deserialize data from a checkpoint without sanitization, which allows arbitrary code execution when processing untrusted input [2][3].

Exploitation

An attacker can craft a malicious pickle payload disguised as a legitimate model checkpoint. If a victim loads this seemingly harmless checkpoint during training (for example, by fetching it from a remote repository), the pickle.load() call executes arbitrary code embedded in the payload [2]. The attack requires user interaction—the victim must be tricked into loading the malicious checkpoint—but does not require prior authentication or network access beyond what is needed to retrieve the file.

Impact

Successful exploitation grants the attacker full remote code execution (RCE) on the victim's machine. This can lead to data exfiltration, system compromise, or further lateral movement within the environment [2].

Mitigation

The vulnerability was addressed in commit 693667b, which removes the vulnerable load_repo_checkpoint() function entirely [3]. Users should update to a patched version of the Transformers library as soon as possible. No workaround exists other than updating, as the unsafe function has been deleted [1][3].

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
transformersPyPI
< 4.38.04.38.0

Affected products

2

Patches

2
693667b8ac81

Remove dead TF loading code (#28926)

1 file changed · +0 50
  • src/transformers/modeling_tf_utils.py+0 50 modified
    @@ -32,7 +32,6 @@
     import h5py
     import numpy as np
     import tensorflow as tf
    -from huggingface_hub import Repository, list_repo_files
     from packaging.version import parse
     
     from . import DataCollatorWithPadding, DefaultDataCollator
    @@ -1356,55 +1355,6 @@ def _save_checkpoint(self, checkpoint_dir, epoch):
             with open(extra_data_path, "wb") as f:
                 pickle.dump(extra_data, f)
     
    -    def load_repo_checkpoint(self, repo_path_or_name):
    -        """
    -        Loads a saved checkpoint (model weights and optimizer state) from a repo. Returns the current epoch count when
    -        the checkpoint was made.
    -
    -        Args:
    -            repo_path_or_name (`str`):
    -                Can either be a repository name for your {object} in the Hub or a path to a local folder (in which case
    -                the repository will have the name of that local folder).
    -
    -        Returns:
    -            `dict`: A dictionary of extra metadata from the checkpoint, most commonly an "epoch" count.
    -        """
    -        if getattr(self, "optimizer", None) is None:
    -            raise RuntimeError(
    -                "Checkpoint loading failed as no optimizer is attached to the model. "
    -                "This is most likely caused by the model not being compiled."
    -            )
    -        if os.path.isdir(repo_path_or_name):
    -            local_dir = repo_path_or_name
    -        else:
    -            # If this isn't a local path, check that the remote repo exists and has a checkpoint in it
    -            repo_files = list_repo_files(repo_path_or_name)
    -            for file in ("checkpoint/weights.h5", "checkpoint/extra_data.pickle"):
    -                if file not in repo_files:
    -                    raise FileNotFoundError(f"Repo {repo_path_or_name} does not contain checkpoint file {file}!")
    -            repo = Repository(repo_path_or_name.split("/")[-1], clone_from=repo_path_or_name)
    -            local_dir = repo.local_dir
    -
    -        # Now make sure the repo actually has a checkpoint in it.
    -        checkpoint_dir = os.path.join(local_dir, "checkpoint")
    -        weights_file = os.path.join(checkpoint_dir, "weights.h5")
    -        if not os.path.isfile(weights_file):
    -            raise FileNotFoundError(f"Could not find checkpoint file weights.h5 in repo {repo_path_or_name}!")
    -        extra_data_file = os.path.join(checkpoint_dir, "extra_data.pickle")
    -        if not os.path.isfile(extra_data_file):
    -            raise FileNotFoundError(f"Could not find checkpoint file extra_data.pickle in repo {repo_path_or_name}!")
    -
    -        # Assuming the repo is real and we got a checkpoint, load the weights and the optimizer state into the model.
    -        # The optimizer state includes the iteration count, so learning rate schedules should resume as normal too.
    -        self.load_weights(weights_file)
    -        with open(extra_data_file, "rb") as f:
    -            extra_data = pickle.load(f)
    -        self.optimizer.set_weights(extra_data["optimizer_state"])
    -
    -        # Finally, return the epoch number from the checkpoint. This isn't a property of the model, so we can't
    -        # set it directly, but the user can pass it to fit().
    -        return {"epoch": extra_data["epoch"]}
    -
         def prepare_tf_dataset(
             self,
             dataset: "datasets.Dataset",  # noqa:F821
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.