XMPP applications often face choices based on the disco#info (see &xep0030;) exposed by other entities. For example, for a client, knowledge about whether a roster entry is a &xep0369; entity or a normal client is important for user experience. It may also be desirable to provide indicators on the type of client a contact is using (mobile or not).
The canonical way to do so has been issueing XEP-0030 requests to the entities emitting presence. This, with the evergrowing featureset of XMPP, induces a lot of traffic for all involed parties, especially during startup. This is a waste of resources, as XEP-0030 information rarely changes and even more, common client configurations and versions share exactly the same information.
&xep0115; has provided the XMPP ecosystem with a way to share this information with less bandwith. Entities using that protocol send a hash of their disco#info result along with presence or stream features. As those hashes can be cached, entities receiving these hashes only need to query the information for each hash once, greatly reducing the Service Discovery traffic.
-However, XEP-0115 has several flaws:
+However, XEP-0115 has two main flaws:
The input to this algorithm is a &xep0030; disco#info <query/> response. The output is an octet string which can be used as input to a hash function or an error.
-General remarks: The algorithm strongly distinguishes between character data (sequences of Unicode code points) and octet strings (sequences of 8-bit bytes). Whenever character data is encoded to octet strings in the following algorithm, the UTF-8 encoding is used. Whenever octet strings are sorted in the following algorithm, the i;octet collation as specified in &rfc4790; is used.
+General remarks: The algorithm strongly distinguishes between character data (sequences of Unicode code points) and octet strings (sequences of 8-bit bytes). Whenever character data is encoded to octet strings in the following algorithm, the UTF-8 encoding as specified in &rfc3629; is used. Whenever octet strings are sorted in the following algorithm, the i;octet collation as specified in &rfc4790; is used.
Processing of <feature/> elements:
@@ -164,13 +171,13 @@The &hashnode; is obtained from a &hash; with the following simple algorithm:
The &hashnode; can be decomposed into its original components with the following algorithm:
Running this octet string through the hash functions leads as to the following &hashset;:
- kzBZbkqJ3ADrj7v08reD1qcWUwNGHaidNUgD7nHpiw8=
- 79mdYAfU9rEdTOcWDO7UEAt6E56SUzk/g6TnqUeuD9Q=
+
+ kzBZbkqJ3ADrj7v08reD1qcWUwNGHaidNUgD7nHpiw8=
+ 79mdYAfU9rEdTOcWDO7UEAt6E56SUzk/g6TnqUeuD9Q=
]]>
Feeding the concatenated octet string as input to the hash functions yields the following &hashset;:
- u79ZroNJbdSWhdSp311mddz44oHHPsEBntQ5b1jqBSY=
- XpUJzLAc93258sMECZ3FJpebkzuyNXDzRNwQog8eycg=
+
+ u79ZroNJbdSWhdSp311mddz44oHHPsEBntQ5b1jqBSY=
+ XpUJzLAc93258sMECZ3FJpebkzuyNXDzRNwQog8eycg=
]]>
The codepoints used for separating the different parts in the Hash Function Input Algortihm (&sepl4; through &sepl1;) are not allowed in well-formed XML character data. As entities are, per &xmppcore;, required to close a stream if non-well-formed XML data is received, these codepoints cannot occur in the input to the algorithm and their use as separators is safe.
+The codepoints used for separating the different parts in the Hash Function Input Algortihm (&sepl1; through &sepl4;) are not allowed in well-formed XML character data. As entities are, per &xmppcore;, required to close a stream if non-well-formed XML data is received, these codepoints cannot occur in the input to the algorithm and their use as separators is safe.
If the algorithm for constructing the input to the hash function or the used hash function itself allow for cheap collisions, caching the hashes will become dangerous as it allows for cache poisoning. This in turn allows entities to effectively fake disco#info responses of other entities.
This was an issue with &xep0115; and has been addressed with a new algorithm for generating the hash function input which keeps the structural information of the disco#info input.
An entity MUST NOT ever use disco#info which has not been verified to belong to a &hash; obtained from a cache using that &hash;. Using cache contents from a trusted source (at the discretion of the entity) counts as verifying.
+A malicious entity could send a large amount of &hashsets; in short intervals, while making sure that it provides matching disco#info responses. If a &procent; uses caching, this can overflow or thrash the caches. &procents; should be aware of this risk and apply proper rate-limiting for processing &hashsets;. To reduce the attack surface, an entity MAY choose to not cache &hashes; obtained from entities not in its roster.
Thanks to the authors of &xep0115; for coming up with the original idea of using presence broadcast to convey service discovery information, as well as the optimization strategies.
The note below the example in Advertisement of Support and Capabilities by Servers has been copied verbatimly from XEP-0115.
Thanks to Waqas Hussain for originally (to my knowledge) pointing out the security flaws in XEP-0115 (see &mlwaqas1;).
+Thanks to Georg Lukas, Link Mauve, Sebastian Riese, Florian Schmaus and Sam Whithed for their input, editorial and otherwise.