The vulnerability lies in the insufficient validation of room upgrade chains within the matrix-js-sdk. The advisory points to MatrixClient::getJoinedRooms, but the provided patch from the official repository modifies the MatrixClient.getVisibleRooms function. It's highly probable that getJoinedRooms is either an alias for, or directly utilizes, getVisibleRooms, making the latter the core of the vulnerability.
The analysis of the commit 43c72d5bf5e2d0a26b3b4f71092e7cb39d4137c4 reveals the exact flaw. The original code in getVisibleRooms would add any room mentioned as a predecessor to a replacedRooms set. It then filtered out any room from the main list that was in this set and had a tombstone event. The critical missing step was to verify that the tombstone event of the old room actually pointed to the new room that was claiming to be the successor. This lack of reciprocal validation is the root cause.
An attacker could exploit this by creating a new room and setting its predecessor state to point to a victim's room. If the victim's room was later tombstoned for any reason, the flawed logic in getVisibleRooms would incorrectly hide the victim's room and effectively replace it with the attacker's room in the user's room list.
The patch rectifies this by replacing the flawed logic with a call to this.findPredecessorRooms and removing the identified predecessors from the set of visible rooms. This new logic, presumably within findPredecessorRooms, correctly validates the entire upgrade chain, ensuring that a room is only considered replaced if there is a valid and verified link from the old room to the new one. The added test case in the patch confirms this by asserting that a room is not hidden when another room claims to replace it without a corresponding tombstone from the original room.