XMPP: logWarning logt volledige stanza XML en decoded JSON — privacy-lek van JIDs, device-ids en ciphertext #1431

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

Bevinding

lib/utils/log.dart stuurt logberichten naar de dart:developer logging stream (DevTools/VM service). Hoewel release builds stil zijn, is in debug builds (ontwikkelaars, testers, anyone met DevTools verbonden) de volledige log zichtbaar. Meerdere logWarning-aanroepen in de XMPP-laag loggen gevoelige data:

Kritiek: volledige stanza XML

lib/xmpp/companion_demux.dart regel 80:

logWarning('xmpp.demux.unknownNamespace', stanza.toXmlString());

Logt de volledige stanza XML bij een onbekende namespace. Dit bevat:

  • from/to JIDs (room@conf/nick — wie is er in de kamer)
  • device-ids in de verzegeling
  • ciphertext in de child-elementen
  • alle stanza-attributen

Een onbekende namespace is precies het scenario waar een vijandige occupant een nep-namespace stuurt om de demux te triggeren — de aanvaller kan de log lezen als hij DevTools-toegang heeft (bijv. een ontwikkelaar die de app test met een vijandige deelnemer).

lib/xmpp/xmpp_transport.dart regel 498 + 302:

static String _stanzaKey(Stanza stanza, String namespace) =>
    '${stanza.id ?? stanza.toXmlString()}:$namespace';

Als een stanza geen id heeft (geldig voor message/presence), wordt de volledige XML in de key gestopt, die bij deferred-expiry wordt gelogd (regel 302).

Gemiddeld: decoded JSON (sealed envelope content)

  • lib/xmpp/xmpp_presence_beacon.dart regel 134: logWarning('xmpp.presence.notObject', decoded) — logt de decoded JSON (sealed envelope met ciphertext)
  • lib/xmpp/xmpp_chat.dart regel 167: logWarning('xmpp.chat.notObject', decoded) — zelfde
  • lib/xmpp/xmpp_chat.dart regel 172: logWarning('xmpp.chat.noSealed', decoded) — zelfde

Dit logt ciphertext en metadata (senderDevice, epoch, nonce) bij een parse-fout. Hoewel ciphertext zelf niet leesbaar is, zijn de metadata (wie stuurt wat, in welke epoch) dat wel.

Trust boundary

Applicatie → Log-output (DevTools/VM service). In debug builds zichtbaar voor iedereen met DevTools-toegang.

Impact

  • JIDs en device-ids in logs onthullen wie er in een samenwerkingssessie zit en met welk device — metadata over deelnemers.
  • Ciphertext in logs is niet direct leesbaar, maar de aanwezigheid en structuur van verzegelingen onthullen patronen (wie stuurt wat, wanneer).
  • Een vijandige occupant kan opzettelijk stanzas met onbekende namespaces sturen om de demux te triggeren en zo de log te vullen met stanza's van andere deelnemers.

Oplossingsrichting

  1. Log nooit stanza.toXmlString(). Vervang door een veilige representatie: stanza.kind.name + stanza.id + stanza.from (afgekapt). Bij geen id, gebruik een hash of een counter, niet de volledige XML.
  2. Log geen decoded JSON. Bij een parse-fout, log alleen het type fout ("not an object", "no sealed field") zonder de data. De data zelf is niet nuttig voor diagnostiek — het type fout wel.
  3. Redigeer JIDs en device-ids in logs. Overweeg een logging-helper die JIDs afkapt (bijv. room@conf/n***) en device-ids hasht (bijv. dev-abc123…).
  4. Aanvullend: de _stanzaKey-helper (xmpp_transport.dart regel 498) moet nooit stanza.toXmlString() gebruiken als fallback — gebruik een hash van de XML of een sequence-nummer.

Locatie

  • lib/xmpp/companion_demux.dart regel 80 (kritiek)
  • lib/xmpp/xmpp_transport.dart regel 498 (indirect via _stanzaKey), regel 302 (logt de key)
  • lib/xmpp/xmpp_presence_beacon.dart regel 134
  • lib/xmpp/xmpp_chat.dart regels 167, 172
  • lib/utils/log.dart (geen redaction)

Severity

MEDIUM — privacy-lek van metadata in debug builds; een vijandige occupant kan het triggeren.

## Bevinding `lib/utils/log.dart` stuurt logberichten naar de `dart:developer` logging stream (DevTools/VM service). Hoewel release builds stil zijn, is in debug builds (ontwikkelaars, testers, anyone met DevTools verbonden) de volledige log zichtbaar. Meerdere `logWarning`-aanroepen in de XMPP-laag loggen gevoelige data: ### Kritiek: volledige stanza XML **`lib/xmpp/companion_demux.dart` regel 80:** ```dart logWarning('xmpp.demux.unknownNamespace', stanza.toXmlString()); ``` Logt de **volledige stanza XML** bij een onbekende namespace. Dit bevat: - `from`/`to` JIDs (room@conf/nick — wie is er in de kamer) - device-ids in de verzegeling - ciphertext in de child-elementen - alle stanza-attributen Een onbekende namespace is precies het scenario waar een vijandige occupant een nep-namespace stuurt om de demux te triggeren — de aanvaller kan de log lezen als hij DevTools-toegang heeft (bijv. een ontwikkelaar die de app test met een vijandige deelnemer). **`lib/xmpp/xmpp_transport.dart` regel 498 + 302:** ```dart static String _stanzaKey(Stanza stanza, String namespace) => '${stanza.id ?? stanza.toXmlString()}:$namespace'; ``` Als een stanza geen `id` heeft (geldig voor message/presence), wordt de volledige XML in de key gestopt, die bij deferred-expiry wordt gelogd (regel 302). ### Gemiddeld: decoded JSON (sealed envelope content) - **`lib/xmpp/xmpp_presence_beacon.dart` regel 134:** `logWarning('xmpp.presence.notObject', decoded)` — logt de decoded JSON (sealed envelope met ciphertext) - **`lib/xmpp/xmpp_chat.dart` regel 167:** `logWarning('xmpp.chat.notObject', decoded)` — zelfde - **`lib/xmpp/xmpp_chat.dart` regel 172:** `logWarning('xmpp.chat.noSealed', decoded)` — zelfde Dit logt ciphertext en metadata (senderDevice, epoch, nonce) bij een parse-fout. Hoewel ciphertext zelf niet leesbaar is, zijn de metadata (wie stuurt wat, in welke epoch) dat wel. ### Trust boundary Applicatie → Log-output (DevTools/VM service). In debug builds zichtbaar voor iedereen met DevTools-toegang. ### Impact - JIDs en device-ids in logs onthullen wie er in een samenwerkingssessie zit en met welk device — metadata over deelnemers. - Ciphertext in logs is niet direct leesbaar, maar de aanwezigheid en structuur van verzegelingen onthullen patronen (wie stuurt wat, wanneer). - Een vijandige occupant kan opzettelijk stanzas met onbekende namespaces sturen om de demux te triggeren en zo de log te vullen met stanza's van andere deelnemers. ### Oplossingsrichting 1. **Log nooit `stanza.toXmlString()`.** Vervang door een veilige representatie: `stanza.kind.name` + `stanza.id` + `stanza.from` (afgekapt). Bij geen `id`, gebruik een hash of een counter, niet de volledige XML. 2. **Log geen decoded JSON.** Bij een parse-fout, log alleen het type fout ("not an object", "no sealed field") zonder de data. De data zelf is niet nuttig voor diagnostiek — het type fout wel. 3. **Redigeer JIDs en device-ids in logs.** Overweeg een logging-helper die JIDs afkapt (bijv. `room@conf/n***`) en device-ids hasht (bijv. `dev-abc123…`). 4. **Aanvullend:** de `_stanzaKey`-helper (xmpp_transport.dart regel 498) moet nooit `stanza.toXmlString()` gebruiken als fallback — gebruik een hash van de XML of een sequence-nummer. ### Locatie - `lib/xmpp/companion_demux.dart` regel 80 (kritiek) - `lib/xmpp/xmpp_transport.dart` regel 498 (indirect via `_stanzaKey`), regel 302 (logt de key) - `lib/xmpp/xmpp_presence_beacon.dart` regel 134 - `lib/xmpp/xmpp_chat.dart` regels 167, 172 - `lib/utils/log.dart` (geen redaction) ### Severity MEDIUM — privacy-lek van metadata in debug builds; een vijandige occupant kan het triggeren.
brenno 2026-08-09 20:56:40 +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#1431
No description provided.