Skip to content
winfunc
Disclosure record · Jitsi Meet

Demoted participants retain moderator recording and dial-out permissions

Temporary promotion overwrote JWT feature restrictions and demotion did not restore them

Jitsi MeetDisclosedSource record

CVSS 3.1 base score

High
8.1/ 10

Vector: CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:H/I:H/A:H

Record

Project
Jitsi Meet
Severity
High8.1
CVE
None listed
Disclosed
Trace
3 steps

Summary

Source

process_and_verify_token()

resources/prosody-plugins/token/util.lib.lua:356

Sink

pre-iq/full hook

resources/prosody-plugins/mod_filter_iq_jibri.lua:49

A token-authenticated participant whose JWT disabled recording, livestreaming, transcription, and outbound calls could retain those capabilities after a legitimate moderator temporarily promoted and then demoted them.

Root cause. process_set_affiliation() copied the granting moderator's jitsi_meet_context_features table into the promoted participant's session. The demotion branch cleared the table only for sessions without auth_token, so token-authenticated sessions retained stale grants that downstream Jibri and Rayo filters treated as authoritative.

Remediation evidence. Jitsi opened PR #17802 the day after the disclosure and merged it on 9 September 2026. The patch restores the participant's original session features when owner status is revoked and adds regression coverage for the role transition.

Severity

Attack vectorAV
Network
Attack complexityAC
High
Privileges requiredPR
Low
User interactionUI
Required
ScopeS
Unchanged
ConfidentialityC
High
IntegrityI
High
AvailabilityA
High

Metric values as published in the disclosure vector. Meters show how far each value raises exposure.

Source-to-sink trace

  1. Source · attacker-controlledresources/prosody-plugins/token/util.lib.lua:356

    process_and_verify_token()

  2. Step 01resources/prosody-plugins/token/util.lib.lua:356

    A valid participant token installs explicit feature restrictions on the authenticated session.

    python
    session.jitsi_meet_context_features = claims["context"]["features"]
    
  3. Step 02resources/prosody-plugins/mod_token_moderation.lua:process_set_affiliation()

    Temporary promotion replaces those restrictions with the granting owner's enabled feature table.

    python
    occupant_session.jitsi_meet_context_features =
      actor_session.jitsi_meet_context_features
    
  4. Step 03resources/prosody-plugins/mod_filter_iq_jibri.lua:49

    After demotion, the stale table remains and the authoritative IQ filter permits recording or livestream operations that the JWT denied.

    python
    if features and features[requested_feature] == true then
      return
    end
    module:fire_event("not-allowed", event)
    
  5. Sinkresources/prosody-plugins/mod_filter_iq_jibri.lua:49

    pre-iq/full hook

Impact

Reported impact

A demoted participant can control same-meeting recording, livestreaming, transcription, or outbound SIP operations. This can expose meeting media, alter recording state, terminate an active stream, or incur telephony usage depending on configured backends.

Attack surface

Token-protected Jitsi conferences using the Prosody moderation bridge and Jibri or Jigasi feature filters.

Preconditions

The attacker is an authenticated participant with restricted JWT features. A legitimate owner must temporarily promote the participant, and the selected Jibri/Jigasi backend must be deployed.

Attack path

  1. 1

    Join with a valid JWT that disables meeting-wide recording and dial-out features.

  2. 2

    Receive a normal temporary owner/moderator promotion.

  3. 3

    Allow the owner to revoke that promotion, or self-demote while still authorized.

  4. 4

    Send a Jibri recording/livestream IQ or a Rayo dial IQ over the same session.

  5. 5

    The filter accepts the stale feature grant despite the current member role and original JWT restriction.

Proof of concept

Reproduction5 stages
  1. 01

    Environment setup

    Use an isolated token-authenticated Jitsi deployment with Jibri or Jigasi enabled and two accounts: an owner and a restricted participant.

  2. 02

    Target configuration

    Give the participant a valid room-scoped JWT whose context.features values explicitly disable recording, livestreaming, transcription, and outbound calling.

  3. 03

    Exploit delivery

    Promote the participant to owner, revoke that affiliation, then send the standard Jibri start/stop or Rayo dial IQ from the participant's existing session.

  4. 04

    Expected response

    On the vulnerable revision, Prosody forwards the IQ instead of returning the expected not-allowed response.

  5. 05

    Outcome

    PR #17802 restores the prior feature table on demotion, so the same IQ is denied after the participant loses owner status.

Remediation

Guidance

Upgrade to a Jitsi Meet release containing PR #17802. Keep verified JWT restrictions immutable or preserve and restore the exact pre-promotion feature state.

Before and after−5+7
if becoming_owner then  occupant.features = actor.featureselseif losing_owner and not occupant.auth_token then  occupant.features = nilendif becoming_owner then  occupant.pre_grant_features = occupant.features  occupant.features = actor.featureselseif losing_owner then  occupant.features = occupant.pre_grant_features  occupant.pre_grant_features = nilend
View original source record

Check the upstream record for the project's current remediation status.

Your codebase

Investigate the paths that matter in your codebase.

Winfunc can trace relevant code paths, preserve supporting evidence, and prepare remediation suggestions for engineering review within an agreed scope.