element-hq / element-hq/element-call

Security: non-cancellable audio transmission without UI indication

Open
#3,138 0 comments 0 reactions 0 assignees View on GitHub
T-Defect
Dominant language
TypeScript
Stars
996
Forks
213
Avg merge
1d 8h
Merged PRs (30d)
55

Description

### Steps to reproduce

When a chat has a bricked call in Element Web (#3100), audio transmission occurs under certain conditions without UI controls to cancel it.

This happens in the default behavior of the "stable" Element Web release at app.element.io with the following conditions:
- enable Element Call embed calls in labs
- use a 3rd party Matrix HS that does not support delayed events
- start a video call using Element Call

This results in a state when UI does not switch to active call UI, but audio transmission is already active. It's not possible to leave the call (or even close the RTCError message with the "close" button), and it's not indicated that audio transmission is active. The victim also does not hear the audio from the attacker, so they have no clue that they are in a call.

### How to "attack"

The attacker has to disable the new MembershipManager in the Element Call developer settings, and place a call to a victim who have not disabled it yet (it's enabled by default).
This way the attacker can join the call properly (playback starts, they can listen to the victim), but the victim has a bricked chat with only their microphone transmitted, but no playback or UI controls.

### How to fix this

- Easy hotfix: make the MembershipManager opt-in instead of opt-out in the default Element Call embed which is used by app.element.io (this leaves the bug open in the case the user enables it in developer settings)
- Correct fix: add ability to Element Call to correctly handle homeservers with no delayed events
- detect the lack of the feature before starting audio stream, or
- cancel audio stream if error occurs

### Temporary workaround

The victim has to disable the new MembershipManager implementation in the developer settings, so they can properly join, and and most importantly: properly leave the call.

If the audio transmission is already active, mute the mic at the OS level. Closing the Element app and reopening it can possibly break the transmission if it does not reconnect, however I have not tested it.

### Affected platforms

Tested with one participant joining the call from 2 devices: macOS Brave browser at app.element.io and an Element X iOS session, both with MembershipManager active. The other participant with 1 device (Linux, Firefox, app.element.io, disabled MembershipManager - so it's properly joined) heard one audio stream, coming either from macOS or the iPhone.
No further testing is done as this issue will likely not receive any attention from the Matrix team at all, so this bug report is probably already a waste of effort.

### Other notes

This is low severity, the data (voice stream) is unlikely to contain sensitive information, as most people is unlikely talk about sensitive info when someone in the room is trying to join a call.

If simply erodes trust in Element and Matrix, especially with non-technical users, who only see that their microphone is transmitted but do not understand why (they may think that Element is buggy and unreliable). Especially in a situation when the "attacker" is actually not an adversary, and notifies the "victim" in another channel that they can hear them in the Element call.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.