Table of Contents

Red Hat’s April 22 advisory for CVE-2026-68591 (CVSS 8.8, CWE-829) identifies a single hardcoded boolean in InstructLab’s linux_train.py as the root cause: trust_remote_code=True passed unconditionally to the transformers from_pretrained() call. Running ilab train, download, or generate against an attacker-controlled HuggingFace repository executes arbitrary Python at the user’s privilege level. No exploit beyond a free HuggingFace account is required.

The Advisory: What Red Hat Disclosed on April 22

CVE-2026-68591 carries a CVSS 3.1 score of 8.8 and is classified under CWE-829 (Inclusion of Functionality from Untrusted Control Sphere). The mechanics are in the Red Hat Bugzilla entry (2): an attacker hosts a model repository on HuggingFace, and any InstructLab user who runs ilab train, download, or generate against that repository triggers arbitrary Python execution at their own privilege level. The attack requires no prior access to the victim system and no interaction beyond convincing a user to point InstructLab at the repository.

The score reflects the threat model: network-reachable, low-complexity, no authentication required on the attacker’s side. The only friction is social engineering.

How linux_train.py Hands HuggingFace the Keys

The mechanism is transformers’ dynamic module loading path3. When trust_remote_code=True is set, transformers downloads .py files from the target repository to a local cache and executes them via importlib.util.spec_from_file_location() and exec_module(). This is not a bug in transformers; it is the intended behavior of the flag. The bug is that InstructLab’s linux_train.py hardcodes it unconditionally.

The flag exists to support model architectures that ship custom Python modeling code alongside their weights, and the from_pretrained() docs are explicit about the risk. Setting it unconditionally in a tool that processes arbitrary user-specified repositories is equivalent to writing AllowUsers * in sshd_config and calling it a feature.

Per the Bugzilla report (2): register a HuggingFace account, push a repository with malicious code in the custom modeling module, point an InstructLab user at the URL. Code runs on their machine at their privilege level, before training starts.

Why Picklescan and ModelScan Are Blind to This Vector

Most ML supply-chain tooling is built around the pickle deserialization threat class, where a malicious .pkl checkpoint embeds executable code in its serialized object graph. That is a well-understood attack surface. This is not that.

picklescan4 scans Python Pickle files for dangerous globals, such as __builtin__ eval in PyTorch checkpoints and .pkl files. It has no inspection path for transformers’ dynamic module loading. ModelScan5 reads serialized model file contents (H5, Pickle, SavedModel, Keras V3) byte-by-byte looking for unsafe code signatures. It does not detect runtime code execution initiated from HuggingFace repositories via trust_remote_code.

Both tools scan artifacts at rest. The trust_remote_code attack runs during a live download-and-import sequence against .py files that look like legitimate model architecture code. A scanner watching for Pickle magic bytes will miss it. A scanner watching for eval in serialized tensors will miss it. Neither tool was built to gate this.

This structural gap has prior art. SGLang’s CVE-2026-5760 showed that Jinja2 chat template execution similarly bypassed scanner tooling by riding a legitimate processing path rather than embedding in serialized weights. The trust_remote_code vector is distinct in mechanics but identical in architecture: a legitimate framework feature, left open unconditionally, invisible to the scanner layer.

The Repo Archive: Where the Fix Should Appear

One day after the advisory, on April 23, the instructlab/instructlab repository was archived by its owner6. Components have been refactored into separate repositories — sdg_hub and training_hub under the Red-Hat-AI-Innovation-Team organization. Training code, where linux_train.py lives, presumably migrated to training_hub.

No fix for CVE-2026-68591 is visible in the new training_hub repository. The archive also complicates patch tracking: the canonical repo is frozen, the successor repos are early-stage, and there is no location where a patch commit is clearly linked to the CVE.

A correct fix removes the hardcoded flag and surfaces it as a user-controlled option, defaulting to False with an explicit opt-in warning. Whether the refactored training code will land with that change, and on what timeline, is not yet clear.

What Operators Should Do Until a Patch Lands

No patch is confirmed available. Mitigations at this point are operational:

Treat any HuggingFace repository as untrusted until audited. The attack requires no special capabilities on the attacker’s side. A plausible model name on a newly registered account is enough.

Do not run ilab train, download, or generate against repositories that have not been reviewed for malicious custom modeling code. This means inspecting .py files in the repository, not just the weights.

Scanner tooling does not close this gap. Running picklescan or modelscan against downloaded checkpoints will not detect a trust_remote_code payload. The attack is not in the checkpoint.

Privilege-scope the ilab process. Code executes at the user’s privilege level. Running InstructLab in a container with minimal host access limits blast radius if a malicious repository is pulled.

The wider implication extends past InstructLab. Any ML tooling that calls from_pretrained() with trust_remote_code=True on user-supplied input has the same attack surface, regardless of what scanner stack runs beside it. The parameter is a code execution gate. Whether it was left open by design or oversight matters less than the fact that it was open.

Frequently Asked Questions

How does CVE-2026-6859 differ from CVE-2026-1839?

CVE-2026-1839 is a pickle-based checkpoint RCE where a malicious .pkl or PyTorch checkpoint embeds executable code in its serialized object graph — the threat class picklescan was built to catch. CVE-2026-6859 is architecturally distinct: the payload is plain Python in .py files executed through transformers’ legitimate importlib dynamic import path, evading every scanner that looks for dangerous globals in serialized weights.

Has any major security publication covered CVE-2026-6859 since disclosure?

As of April 28, six days after the Red Hat advisory, no mainstream security outlet has published analysis. The NVD entry and Bugzilla report remain the only authoritative public sources. Teams relying on vulnerability roundup newsletters or security feed aggregators for triage may not have this CVE on their radar yet.

What CI gate would cover this if picklescan and modelscan cannot?

Two options close the gap: statically analyze .py files in a repository’s modeling code directory for dangerous calls (subprocess, os.system, socket) before passing the repo to InstructLab, or enforce trust_remote_code=False at the transformers configuration level so from_pretrained() refuses to execute remote code regardless of what the calling tool requests. The latter is more reliable because it disables the code-loading path entirely rather than trying to classify which .py files are malicious.

Does HuggingFace enforce any platform-level control over trust_remote_code?

No. The flag is a consumer-side parameter with no server-side enforcement. HuggingFace’s platform does not gate, warn about, or audit trust_remote_code at download time. The trust decision is made entirely by whichever application calls from_pretrained(), so a hardcoded True in InstructLab opts the user into code execution with no platform-mediated consent step.

Footnotes

  1. CVE-2026-6859 2 3 4

  2. Red Hat Bugzilla 2459998 2

  3. transformers dynamic_module_utils.py

  4. picklescan

  5. ModelScan

  6. instructlab/instructlab archived repository 2

Sources

  1. CVE-2026-6859primaryaccessed 2026-04-29
  2. Red Hat Bugzilla 2459998primaryaccessed 2026-04-29
  3. transformers dynamic_module_utils.pyprimaryaccessed 2026-04-29
  4. picklescancommunityaccessed 2026-04-29
  5. ModelScancommunityaccessed 2026-04-29
  6. instructlab/instructlab archived repositoryprimaryaccessed 2026-04-29

Enjoyed this article?

Stay updated with our latest insights on AI and technology.