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 at the time of publication

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-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-87988

September 11, 2026

_READ_ONLY_COMMANDS_POSIX expansion adds 31 commands with no path checking, granting unconditional access to the full host filesystem

Mistral Vibe

Mistral Vibe automatically approves a large set of commands that are not subject to the expected workspace path restrictions, allowing files anywhere on the host to be accessed without user approval.

September 2026
CVE-2026-87987

September 11, 2026

Environment variable prefixes stripped from permission check enable RCE via env injection

Mistral Vibe

Mistral Vibe does not consider environment variable assignments when checking whether a command can run without approval, allowing environment controlled behavior in allowlisted programs such as Git to be abused for arbitrary code execution.

September 2026