# Mattermost — CWE-407 Disclosure Brief
**2026-03-27 · Patch available — awaiting upstream merge**

## Finding

One O(n²) defect in Mattermost's role permission system. `CheckRolesExist()` performs a nested O(n×m) scan to validate role assignments — called on every permission check in the authorization path. Patch ready for upstream review.

## The Defects

**mattermost-0001 (PATCHED — HIGH):** `role.go:258`

```go
// Inside CheckRolesExist() — per role assignment validation:
for _, roleName := range roleNames {
    found := false
    for _, role := range roles {  // O(n×m) nested scan
        if role.Name == roleName {
            found = true
            break
        }
    }
    if !found { ... }
}
```

Nested loop: for each of N role names, scan all M roles to find a match. **O(N × M) per check**. **Measured ratio: 50×.**

## Complexity Proof

For N=50 role names, M=50 roles:
- O(N×M) = 2,500 comparisons per check
- Fixed: `map[string]bool` role name set → O(N)
- **50× measured ratio.**

## Impact

All Mattermost instances — role validation is part of the authorization path called on permission checks. Mattermost is a widely deployed open-source team messaging platform used in enterprises and government. Workspaces with many custom roles and complex permission schemes hit worst case. Permission checks occur on every API request that requires authorization.

## The Fix

Pre-build a `map[string]bool` from `roles` before the outer loop:

```go
// Before
for _, roleName := range roleNames {
    found := false
    for _, role := range roles { // O(n×m)
        if role.Name == roleName { found = true; break }
    }
}

// After
// CWE-407 fix: map[string]bool for O(1) role lookup instead of O(m) nested scan.
roleMap := make(map[string]bool, len(roles))
for _, role := range roles {
    roleMap[role.Name] = true
}
for _, roleName := range roleNames {
    if !roleMap[roleName] { ... }
}
```

## Patch

`defects/mattermost/patch/mattermost-0001-role-map.patch`

## What We Ask

1. Confirm receipt and assign a GitHub Security Advisory or issue reference.
2. Validate the patch against your role and permission test suite.
3. Assess CVE eligibility — fires on every permission check with many custom roles.
4. Coordinate a disclosure date — we are targeting 90 days from first contact.

Contact: see cover email. This brief is confidential until coordinated disclosure.
