XMPP: key-exchange stanza.from null-fallback is inconsistent — keyshare met null from vindt geen kandidaten #1429

Closed
opened 2026-08-09 18:35:00 +00:00 by brenno · 0 comments
Owner

Bevinding

lib/xmpp/xmpp_key_exchange.darthandleDevicePresence (regel 225) en handleKeyshare (regel 254) gebruiken beide stanza.from ?? roomJid als fallback voor een null from. Maar de fallback is semantisch inconsistent tussen de twee handlers:

  • handleDevicePresence ingest een device met peerAddress = stanza.from ?? roomJid. Als from null is, wordt het device geassocieerd met roomJid (room@conf, zonder nick).
  • handleKeyshare zoekt kandidaten met directory.devicesForAddress(stanza.from ?? roomJid). Als from null is, zoekt hij devices met peerAddress == roomJid.

Als from null is voor een device-presence, wordt het device geassocieerd met roomJid. Als from null is voor een keyshare, zoekt hij devices met peerAddress == roomJid — en vindt de device die met roomJid was geassocieerd. Dat is intern consistent.

Maar de echte bug is: als from null is voor een device-presence, wordt het device geassocieerd met roomJid in plaats van met room@conf/nick. Later, als een keyshare aankomt mét from = room@conf/nick (de normale situatie), zoekt handleKeyshare naar devices met peerAddress == room@conf/nick — en vindt de device niet, want die is geassocieerd met roomJid.

Wat er gebeurt

  1. Een buggy/vijandige server stuurt een device-presence met from = null (of een stanza zonder from-attribuut).
  2. handleDevicePresence ingest het device met peerAddress = roomJid.
  3. De autoriteit stuurt een keyshare met from = room@conf/nick (normaal).
  4. handleKeyshare zoekt directory.devicesForAddress(room@conf/nick) — vindt niets.
  5. De keyshare wordt gedropt (regel 257, logWarning('xmpp.keyexchange.keyshare.unknownSender', ...)).
  6. De deelnemer wordt nooit gesleuteld en kan niet meedoen.

Trust boundary

MUC-server → Applicatie (key-exchange). Een buggy of vijandige server stuurt presence zonder from.

Impact

Een deelnemer wiens device-presence zonder from arriveert, wordt verkeerd geassocieerd en kan nooit gesleuteld worden. De keyshare vindt geen kandidaat en wordt gedropt. De deelnemer is permanent uitgesloten van de samenwerking zonder foutmelding.

Oplossingsrichting

  1. Dropp stanzas zonder from in de key-exchange. Een MUC-presence of groupchat-message zonder from is geen geldige MUC-stanza (XEP-0045 §7.2.1 — de server zet altijd een from met de occupant-JID). Dropp de stanza fail-closed in plaats van een semantisch incorrecte fallback te gebruiken:
if (stanza.from == null) return; // geen geldige MUC-stanza

Dit in zowel handleDevicePresence als handleKeyshare.

  1. Aanvullend: als de fallback om een reden behouden moet blijven, maak hem dan consistent — gebruik in beide handlers dezelfde fallback-logica, en zorg dat devicesForAddress ook devices vindt die met een afgeleide van roomJid zijn geassocieerd. Maar optie 1 is eenvoudiger en veiliger.

Locatie

  • lib/xmpp/xmpp_key_exchange.dart regel 225 (handleDevicePresence fallback), regel 254 (handleKeyshare fallback), regel 255 (devicesForAddress lookup)
  • lib/collab/collab_device_directory.dart regels 147–150 (devicesForAddress — filtert op exacte peerAddress-match)

Severity

MEDIUM — een buggy server kan een deelnemer permanent uitsluiten van keying.

## Bevinding `lib/xmpp/xmpp_key_exchange.dart` — `handleDevicePresence` (regel 225) en `handleKeyshare` (regel 254) gebruiken beide `stanza.from ?? roomJid` als fallback voor een null `from`. Maar de fallback is semantisch inconsistent tussen de twee handlers: - `handleDevicePresence` ingest een device met `peerAddress = stanza.from ?? roomJid`. Als `from` null is, wordt het device geassocieerd met `roomJid` (`room@conf`, zonder nick). - `handleKeyshare` zoekt kandidaten met `directory.devicesForAddress(stanza.from ?? roomJid)`. Als `from` null is, zoekt hij devices met `peerAddress == roomJid`. Als `from` null is voor een device-presence, wordt het device geassocieerd met `roomJid`. Als `from` null is voor een keyshare, zoekt hij devices met `peerAddress == roomJid` — en vindt de device die met `roomJid` was geassocieerd. Dat is intern consistent. Maar de echte bug is: als `from` null is voor een device-presence, wordt het device geassocieerd met `roomJid` in plaats van met `room@conf/nick`. Later, als een keyshare aankomt mét `from = room@conf/nick` (de normale situatie), zoekt `handleKeyshare` naar devices met `peerAddress == room@conf/nick` — en vindt de device niet, want die is geassocieerd met `roomJid`. ### Wat er gebeurt 1. Een buggy/vijandige server stuurt een device-presence met `from = null` (of een stanza zonder `from`-attribuut). 2. `handleDevicePresence` ingest het device met `peerAddress = roomJid`. 3. De autoriteit stuurt een keyshare met `from = room@conf/nick` (normaal). 4. `handleKeyshare` zoekt `directory.devicesForAddress(room@conf/nick)` — vindt niets. 5. De keyshare wordt gedropt (regel 257, `logWarning('xmpp.keyexchange.keyshare.unknownSender', ...)`). 6. De deelnemer wordt nooit gesleuteld en kan niet meedoen. ### Trust boundary MUC-server → Applicatie (key-exchange). Een buggy of vijandige server stuurt presence zonder `from`. ### Impact Een deelnemer wiens device-presence zonder `from` arriveert, wordt verkeerd geassocieerd en kan nooit gesleuteld worden. De keyshare vindt geen kandidaat en wordt gedropt. De deelnemer is permanent uitgesloten van de samenwerking zonder foutmelding. ### Oplossingsrichting 1. **Dropp stanzas zonder `from` in de key-exchange.** Een MUC-presence of groupchat-message zonder `from` is geen geldige MUC-stanza (XEP-0045 §7.2.1 — de server zet altijd een `from` met de occupant-JID). Dropp de stanza fail-closed in plaats van een semantisch incorrecte fallback te gebruiken: ```dart if (stanza.from == null) return; // geen geldige MUC-stanza ``` Dit in zowel `handleDevicePresence` als `handleKeyshare`. 2. **Aanvullend:** als de fallback om een reden behouden moet blijven, maak hem dan consistent — gebruik in beide handlers dezelfde fallback-logica, en zorg dat `devicesForAddress` ook devices vindt die met een afgeleide van `roomJid` zijn geassocieerd. Maar optie 1 is eenvoudiger en veiliger. ### Locatie - `lib/xmpp/xmpp_key_exchange.dart` regel 225 (`handleDevicePresence` fallback), regel 254 (`handleKeyshare` fallback), regel 255 (`devicesForAddress` lookup) - `lib/collab/collab_device_directory.dart` regels 147–150 (`devicesForAddress` — filtert op exacte `peerAddress`-match) ### Severity MEDIUM — een buggy server kan een deelnemer permanent uitsluiten van keying.
brenno 2026-08-09 20:56:37 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
LibreKAT/Ocideck#1429
No description provided.