SAI Security Advisory

V1 API Tenant Isolation Bypass via Null Tenant/Database Context

June 12, 2026

CVE Number

CVE-2026-45832

Summary

All V1 collection-level endpoints pass None for tenant and database to the authorization layer, making tenant-scoped access control impossible through V1, regardless of which authorization provider is configured. V1 cannot be disabled. Combined with CVE-2026-45830, any authenticated user has unrestricted read/write access to any collection by UUID through V1 endpoints.

Products Impacted

This vulnerability affects ChromaDB versions from 0.5.0 to the latest Python release.

CVSS Score: 8.8

CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:N/SC:H/SI:H/SA:N

CWE Categorization

CWE-862: Missing Authorization 

CWE-639: Authorization Bypass Through User-Controlled Key

Details

V1 endpoints in chromadb/server/fastapi/__init__.py systematically pass None for tenant and database to the auth layer. Every V1 collection-level endpoint follows the same pattern, marked with the comment # NOTE(rescrv, iron will auth): v1.

V1 add endpoint, __init__.py:1993-2011:

@trace_method("FastAPI.add_v1", OpenTelemetryGranularity.OPERATION)
@rate_limit
async def add_v1(
    self,
    request: Request,
    collection_id: str,
) -> bool:
    try:
        def process_add(request: Request, raw_body: bytes) -> bool:
            add = validate_model(AddEmbedding, orjson.loads(raw_body))
            # NOTE(rescrv, iron will auth):  v1
            self.sync_auth_and_get_tenant_and_database_for_request(
                request.headers,
                AuthzAction.ADD,
                None,  # The tenant is always None
                None,  # The database is always None
                collection_id,
            )
            return self._api._add(
                collection_id=_uuid(collection_id),  # The UUID goes directly to _add
                # ...
            )

V1 get endpoint, __init__.py:2114-2130:

@trace_method("FastAPI.get_v1", OpenTelemetryGranularity.OPERATION)
@rate_limit
async def get_v1(
    self,
    collection_id: str,
    request: Request,
) -> GetResult:
    def process_get(request: Request, raw_body: bytes) -> GetResult:
        get = validate_model(GetEmbedding, orjson.loads(raw_body))
        # NOTE(rescrv, iron will auth):  v1
        self.sync_auth_and_get_tenant_and_database_for_request(
            request.headers,
            AuthzAction.GET,
            None,  # The tenant is always None
            None,  # The database is always None
            collection_id,
        )
        return self._api._get(
            collection_id=_uuid(collection_id),  # The UUID goes straight to _get
            # ...
        )

The None values propagate into AuthzResource(tenant=None, database=None, collection=collection_id). Even if an authorization provider attempted to check the resource, it would have no tenant or database to check against. The data layer then calls _get_collection(uuid), which resolves the collection by UUID without any tenant filtering.

Timeline

  • February 17th, 2026 - Initial disclosure to ChromaDB per their security page https://www.trychroma.com/security
  • February 24th, 2026 - Attempted follow up through other trychroma emails.
  • March 5th, 2026 - Attempted contact through IT-ISAC.
  • April 16th, 2026 - Attempted final follow up through all previous channels and social media.
  • May 18th, 2026 - Publicly disclosed a first vulnerability, no response from the vendor.

Project URL:

https://www.trychroma.com/

https://github.com/chroma-core/chroma/

RESEARCHER: Esteban Tonglet, Security Researcher, HiddenLayer

Related SAI Security Advisory

CVE-2026-45833

June 12, 2026

Post-Authentication RCE via update_collection

ChromaDB

Any authenticated user with UPDATE_COLLECTION permission can achieve remote code execution by updating a collection's embedding function to reference a malicious HuggingFace model with trust_remote_code: true. The update_collection endpoint uses the same build_from_config() code path as CVE-2026-45829. Authentication runs before model loading, so this is not a pre-authentication issue, but the model instantiation itself is unguarded.

June 2026
CVE-2026-45832

June 12, 2026

V1 API Tenant Isolation Bypass via Null Tenant/Database Context

ChromaDB

All V1 collection-level endpoints pass None for tenant and database to the authorization layer, making tenant-scoped access control impossible through V1, regardless of which authorization provider is configured. V1 cannot be disabled. Combined with CVE-2026-45830, any authenticated user has unrestricted read/write access to any collection by UUID through V1 endpoints.

June 2026