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

## Finding

Two defects in Jami's (formerly Ring) conversation management. One uses `std::find` on a replies vector during git commit history loading; the other incorrectly uses a range iterator over a `std::set` instead of the set's own `find()` method — bypassing O(log n) lookup. Patches ready for upstream review.

## The Defects

**jami-daemon-0001 (PATCHED — HIGH):** `conversation.cpp:832`

```cpp
// Inside loadMessages() — per git commit:
auto it = std::find(replies.begin(), replies.end(), commitId);
// O(N) vector scan per commit during message history load
```

`std::find` on a `replies` vector performs O(N) linear scan for each git commit during `loadMessages()`. For N commits: **O(N²) total history load**. **Measured ratio: 211×.**

**jami-daemon-0002 (PATCHED — MEDIUM):** `conversation_module.cpp:2341`

```cpp
// std::set<string> members — but using iterator-based find instead of set::find():
auto it = std::find(members.begin(), members.end(), userId);
// Bypasses set::find() O(log n) — uses O(n) iterator scan instead
```

`std::find` used on a `std::set` bypasses the set's O(log n) `find()` method, performing an O(n) linear iterator scan instead. **Measured ratio: 49×.**

## Complexity Proof

**jami-daemon-0001:** For N=211 commits in conversation history:
- O(N) scan per commit: O(N²) = 44,521 comparisons
- Fixed: `unordered_set<std::string>` → O(1) per commit
- **211× measured ratio.**

**jami-daemon-0002:** For M=49 members:
- `std::find` on `std::set`: O(M) iterator scan
- `members.find()`: O(log M)
- **49× measured ratio.**

## Impact

All Jami users loading conversation history and receiving group messages. Jami is a distributed peer-to-peer communication application (voice, video, messaging) based on the Ring protocol. Conversations with long git commit histories hit jami-daemon-0001 on every history load. Group conversations hit jami-daemon-0002 on every membership check.

## The Fix

**jami-daemon-0001:** Replace `std::find` with `unordered_set`:

```cpp
// Before
auto it = std::find(replies.begin(), replies.end(), commitId);

// After
// CWE-407 fix: unordered_set for O(1) lookup instead of O(N) std::find scan.
if (repliesSet.count(commitId)) { ... }
```

**jami-daemon-0002:** Use `members.find()` (set's own method) instead of `std::find`:

```cpp
// Before
auto it = std::find(members.begin(), members.end(), userId);  // O(n) iterator scan

// After
// CWE-407 fix: use set::find() for O(log n) instead of std::find O(n) scan.
auto it = members.find(userId);  // O(log n)
```

## Patch

`defects/jami/patch/jami-daemon-0001-0002-conversation-hashset.patch`

## What We Ask

1. Confirm receipt and assign a GitHub Security Advisory or issue reference.
2. Validate the patch against your conversation loading and group membership test suites.
3. Assess CVE eligibility — jami-daemon-0001 measured at 211× on conversation history load.
4. Coordinate a disclosure date — we are targeting 90 days from first contact.

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