SAI Security Advisory

RBAC Authorization Bypass: Resource Context Ignored

June 12, 2026

CVE Number

CVE-2026-45831

Summary

ChromaDB's SimpleRBACAuthorizationProvider, the only built-in RBAC provider and the one used in all official documentation examples, evaluates whether a user holds a given permission but never checks which tenant, database, or collection that permission applies to. A user configured with read access to a specific tenant can read from any tenant. A user with write access can modify data across all tenants.

Products Impacted

This vulnerability affects ChromaDB versions from 0.5.0 to the latest release, 1.5.9

CVSS Score: 8.9

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

CWE Categorization

CWE-863: Incorrect Authorization

Details

The vulnerability is in chromadb/auth/simple_rbac_authz/__init__.py:40-75. The initialization code builds a mapping of user_id -> set(actions):

class SimpleRBACAuthorizationProvider(ServerAuthorizationProvider):
    def __init__(self, system: System):
        super().__init__(system)
        # ...
        # This AuthorizationProvider does not support
        # per-resource authorization so we just map the user ID to the
        # permissions they have.
        self._permissions: Dict[str, Set[str]] = {}
        for user in self._config["users"]:
            _actions = self._config["roles_mapping"][user["role"]]["actions"]
            self._permissions[user["id"]] = set(_actions)

The authorization decision in authorize_or_raise() only checks whether the user’s action set contains the requested action:

def authorize_or_raise(
    self, user: UserIdentity, action: AuthzAction, resource: AuthzResource
) -> None:
    policy_decision = False
    if (
        user.user_id in self._permissions
        and action in self._permissions[user.user_id]  # Only checks action
    ):
        policy_decision = True

    logger.debug(
        f"Authorization decision: Access "
        f"{'granted' if policy_decision else 'denied'} for "
        f"user [{user.user_id}] attempting to "
        f"[{action}] [{resource}]" 
    )
    if not policy_decision:
        raise HTTPException(status_code=403, detail="Forbidden")

The resource parameter is of type AuthzResource, defined at chromadb/auth/__init__.py:186-194:

@dataclass
class AuthzResource:
    tenant: Optional[str]
    database: Optional[str]
    collection: Optional[str]

It carries the tenant, database, and collection context for the authorization decision, but authorize_or_raise() never reads resource.tenant, resource.database, or resource.collection. The decision is purely action in permissions[user_id].

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