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

## Finding

Two O(n²) defects in Rocket.Chat's notification dispatch pipeline. Both use `Array.includes()` in per-message hot paths — one for mention/thread subscriber filtering, the other for subscription update deduplication. Measured at 200× and 30×. Patches ready for upstream review.

## The Defects

**rocketchat-0001 (PATCHED — HIGH):** `sendNotificationsOnMessage.ts:79`

```typescript
// Per subscriber, per message with mentions/threads:
if (mentionIds.includes(userId) || usersInThread.includes(userId)) {
    // O(S×M) total — S subscribers × M mentions
}
```

`mentionIds.includes()` and `usersInThread.includes()` both perform O(M) and O(T) array scans per subscriber. For S subscribers, M mentions, T thread users: **O(S × (M + T)) per message**. **Measured ratio: 200×.**

**rocketchat-0002 (PATCHED — MEDIUM):** `notifyUsersOnMessage.ts:129`

```typescript
// Per subscription in updateUsersSubscriptions:
if (userIds.includes(userId)) {  // O(U) Array.includes() per subscription
    ...
}
```

`userIds.includes()` performs O(U) scan per subscription during user notification update. **Measured ratio: 30×.**

## Complexity Proof

**rocketchat-0001:** For S=1000 subscribers, M=200 mentioned users:
- Per message: S × M = 200,000 array comparisons
- Fixed: `new Set(mentionIds)` → S × O(1)
- **200× measured ratio.**

**rocketchat-0002:** For U=30 notified users:
- Per subscription: O(U) scan → **30× measured ratio.**

## Impact

All Rocket.Chat workspaces — notifications are a core feature used by every message sent. Busy channels with many subscribers and mention-heavy messages (team announcements, @room, @here) hit rocketchat-0001 on every message. Large workspaces with thousands of users are most affected. Rocket.Chat is a widely deployed open-source team communication platform used in enterprises and government.

## The Fix

**rocketchat-0001:** Pre-build `Set` from `mentionIds` and `usersInThread`:

```typescript
// Before
if (mentionIds.includes(userId) || usersInThread.includes(userId)) { ... }

// After
// CWE-407 fix: Set for O(1) has() instead of O(M) Array.includes() scan.
const mentionSet = new Set(mentionIds);
const threadSet = new Set(usersInThread);
if (mentionSet.has(userId) || threadSet.has(userId)) { ... }
```

**rocketchat-0002:** Replace `userIds` array with `Set` before the subscription loop.

## Patch

`defects/rocketchat/patch/rocketchat-0001-0002-notification-set.patch`

## What We Ask

1. Confirm receipt and assign a GitHub Security Advisory or issue reference.
2. Validate the patch against your notification dispatch test suite.
3. Assess CVE eligibility — rocketchat-0001 fires on every message in channels with mentions.
4. Coordinate a disclosure date — we are targeting 90 days from first contact.

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