llamaIndex - ✅(Solved) Fix llama-index-embeddings-adapter: torch.load() without weights_only=True allows pickle deserialization [1 pull requests, 4 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
run-llama/llama_index#21465Fetched 2026-04-25 06:03:18
View on GitHub
Comments
4
Participants
3
Timeline
9
Reactions
0
Timeline (top)
commented ×4mentioned ×2subscribed ×2cross-referenced ×1

BaseAdapter.load() in llama-index-embeddings-adapter calls torch.load() without weights_only=True. Since PyTorch 1.13+, omitting this parameter is deprecated and triggers a FutureWarning; in future PyTorch versions it will default to True. More importantly, loading an untrusted .bin file with the current code allows arbitrary code execution via Python's pickle deserialization.

Root Cause

BaseAdapter.load() in llama-index-embeddings-adapter calls torch.load() without weights_only=True. Since PyTorch 1.13+, omitting this parameter is deprecated and triggers a FutureWarning; in future PyTorch versions it will default to True. More importantly, loading an untrusted .bin file with the current code allows arbitrary code execution via Python's pickle deserialization.

Fix Action

Fixed

PR fix notes

PR #21470: fix: add weights_only=True to torch.load() in embeddings adapter

Description (problem / solution / changelog)

…execution

Description

Fixes a security vulnerability in BaseAdapter.load() in llama-index-embeddings-adapter where torch.load() was called without weights_only=True.

Without this parameter, loading an untrusted .bin file allows arbitrary code execution via Python's pickle deserialization. An attacker could publish a malicious pytorch_model.bin file that executes shell commands when loaded by a victim.

Fixes #21465

New Package?

  • Yes
  • No

Version Bump?

  • Yes
  • No

Type of Change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Your pull-request will likely not be merged unless it is covered by some form of impactful unit testing.

  • I added new unit tests to cover this change
  • I believe this change is already covered by existing unit tests

Suggested Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added Google Colab support for the newly added notebooks.
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I ran uv run make format; uv run make lint to appease the lint gods

Changed files

  • llama-index-integrations/embeddings/llama-index-embeddings-adapter/llama_index/embeddings/adapter/utils.py (modified, +1/-0)
  • llama-index-integrations/embeddings/llama-index-embeddings-adapter/tests/test_embeddings_adapter.py (modified, +27/-0)

Code Example

@classmethod
def load(cls, input_path: str) -> "BaseAdapter":
    """Load model."""
    with open(os.path.join(input_path, "config.json")) as fIn:
        config = json.load(fIn)
    model = cls(**config)
    model.load_state_dict(
        torch.load(                                      # ← no weights_only=True
            os.path.join(input_path, "pytorch_model.bin"),
            map_location=torch.device("cpu"),
        )
    )
    return model

---

model.load_state_dict(
    torch.load(
        os.path.join(input_path, "pytorch_model.bin"),
        map_location=torch.device("cpu"),
        weights_only=True,   # ← safe: only loads tensor weights, no pickle execution
    )
)

---

from safetensors.torch import load_file
state_dict = load_file(os.path.join(input_path, "model.safetensors"))
model.load_state_dict(state_dict)
RAW_BUFFERClick to expand / collapse

Issue Title

llama-index-embeddings-adapter: torch.load() without weights_only=True allows arbitrary code execution via pickle

Summary

BaseAdapter.load() in llama-index-embeddings-adapter calls torch.load() without weights_only=True. Since PyTorch 1.13+, omitting this parameter is deprecated and triggers a FutureWarning; in future PyTorch versions it will default to True. More importantly, loading an untrusted .bin file with the current code allows arbitrary code execution via Python's pickle deserialization.

Affected File

llama-index-integrations/embeddings/llama-index-embeddings-adapter/llama_index/embeddings/adapter/utils.py (confirmed on llama-index-core==0.14.21, commit a3aeb31)

Vulnerable Code

@classmethod
def load(cls, input_path: str) -> "BaseAdapter":
    """Load model."""
    with open(os.path.join(input_path, "config.json")) as fIn:
        config = json.load(fIn)
    model = cls(**config)
    model.load_state_dict(
        torch.load(                                      # ← no weights_only=True
            os.path.join(input_path, "pytorch_model.bin"),
            map_location=torch.device("cpu"),
        )
    )
    return model

input_path is passed directly from the caller (AdapterEmbeddingModel.__init__ via adapter_path argument), making it user-controlled.

Attack Scenario

  1. Attacker publishes a HuggingFace Hub repository containing a malicious pytorch_model.bin (a pickled object with __reduce__ that executes a shell command).
  2. A user who fine-tuned an adapter model downloads it and loads it via AdapterEmbeddingModel(adapter_path="attacker/malicious-adapter", ...).
  3. torch.load("pytorch_model.bin") deserializes the pickle payload → arbitrary code execution on the user's machine.

Impact

Arbitrary code execution at model-load time for any user who loads an adapter from an untrusted path.

Suggested Fix

model.load_state_dict(
    torch.load(
        os.path.join(input_path, "pytorch_model.bin"),
        map_location=torch.device("cpu"),
        weights_only=True,   # ← safe: only loads tensor weights, no pickle execution
    )
)

If the adapter structure requires non-tensor objects that weights_only=True cannot handle, consider using safetensors format instead:

from safetensors.torch import load_file
state_dict = load_file(os.path.join(input_path, "model.safetensors"))
model.load_state_dict(state_dict)

Reference

Discovery

Found via static analysis of the llama_index codebase.

extent analysis

TL;DR

To prevent arbitrary code execution via pickle deserialization, set weights_only=True when calling torch.load() in the BaseAdapter.load() method.

Guidance

  • Verify the vulnerability by checking if weights_only=True is set in the torch.load() call in the BaseAdapter.load() method.
  • Apply the suggested fix by adding weights_only=True to the torch.load() call to ensure only tensor weights are loaded, preventing pickle execution.
  • Consider using the safetensors format as an alternative to handle non-tensor objects that weights_only=True cannot handle.
  • Review the PyTorch security documentation and the referenced CVE to understand the implications of unsafe deserialization with torch.load().

Example

model.load_state_dict(
    torch.load(
        os.path.join(input_path, "pytorch_model.bin"),
        map_location=torch.device("cpu"),
        weights_only=True,   # ← safe: only loads tensor weights, no pickle execution
    )
)

Notes

The suggested fix assumes that the adapter structure only requires tensor weights. If non-tensor objects are necessary, using the safetensors format may be a viable alternative.

Recommendation

Apply the workaround by setting weights_only=True in the torch.load() call to prevent arbitrary code execution via pickle deserialization. This fix is a safe and straightforward solution to mitigate the vulnerability.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING