XMPP: Admin-in-the-middle

XMPP: Admin-in-the-middle

Every time somebody discusses instant messaging, at least one person shows up and recommends XMPP. We talked about myths of federation last time and showed you that there are several issues with XMPP. However, some people still consider XMPP to be an extremely privacy-friendly way of messaging nowadays.

In this article, we show you the power of an XMPP server admin and encourage you to always use your own XMPP server (or switch to more secure services).


  1. Setup
  2. Test 1: Monitor all connections
  3. Test 2: Use ejabberdctl for information gathering
  4. Test 3: Analyze the Mnesia database
  5. Test 4: See content of messages and passwords in cleartext
  6. Test 5: Manipulate user data
  7. Lessons learned
  8. Summary
  9. Links
  10. Sources
  11. Changelog

Always stay in the loop!
Subscribe to our RSS/Atom feeds.



For our experiment, we installed the latest version of ejabberd (18.06) on Debian 9. We mostly didn’t change the defaults. This doesn’t matter since the end user can’t see most of the configuration when connected to an XMPP server.

In ejabberd.yml, we added the domain name and IP address of our server and enabled “in-band registration”. Furthermore, we opened the ports 5222 (client-to-server connections, c2s) and 5269 (server-to-server connections, s2s).


We used three clients. Two Android phones had Conversations 2.2.8 (via F-Droid) and one Linux device had Gajim 1.0.3 installed.

Test 1: Monitor all connections

First of all, we wanted to monitor all c2s and all s2s connections. This is quite simple since you only need tcpdump or Wireshark. We ran tcpdump on the server and used another computer for monitoring:

#! /bin/bash
mkfifo /tmp/pcap_file
ssh [username]@[xmppserver] "tcpdump -n -w - -i ens3 '(port 5222) or (port 5269)'" > /tmp/pcap_file
wireshark -k -i /tmp/pcap_file

This allowed us to monitor all XMPP-relevant connections in real time. The result:

  • We see all public IP addresses of users of our XMPP server
  • We see all IP addresses of other servers which host users who chat with users of our server

Of course, this includes metadata like:

  • IP addresses of sender and receiver of each packet
  • timestamps
  • approximate location based on the IP address
  • bytes transmitted (one can differentiate between actual messages and XMPP status messages)
  • number of packets sent/received
  • etc.
Note that since TLS encryption is in place by default, we weren't able to directly see the content of these packets. The above-mentioned metadata is also visible for the company which provides this server and any network-level third party.

Having said this, we noted that the default TLS configuration of ejabberd is not that secure:

  • TLS 1.0, TLS 1.1 and TLS 1.2 are enabled (only TLS 1.2 and 1.3 are recommended)
  • self-signed certificate using RSA (2048 bit) (use one signed by a CA)
  • Key sizes of 256 bits (ECC) resp. 1024 bits (DH) for key exchange (use 384+ bits resp. 2048+ bits)
  • Several cipher suites don’t support perfect forward secrecy and/or AEAD
Part of the default TLS configuration of ejabberd. Especially, weak DH params (1024 bit) and outdated TLS versions (1.0 and 1.1) should be disabled.
Part of the default TLS configuration of ejabberd. Especially, weak DH params (1024 bit) and outdated TLS versions (1.0 and 1.1) should be disabled. (🔍 Zoom in)

Note that several XMPP server admins started to harden their servers for better transport security. This makes it impossible to establish server-to-server connections with their hardened servers if you use the defaults here.

Feedback of our readers

One reader considered this first test invalid due to unknown reasons.

Admins, server providers, ISPs and some other third parties are able to monitor traffic even if TLS is in use. Since XMPP ports are well-known and there is even cleartext XMPP traffic sent by default, third parties are able to identify this traffic. Of course, this is also true for other services. We never denied this. The first test is about awareness for XMPP metadata and passive network surveillance.

Test 2: Use ejabberdctl for information gathering

ejabberdctl is an administration script and very powerful. The server admin can use it to gather information about all server users. For instance:

  • See all users connected to the server (connected_users_info), including JID, type of connection, IP address, port number, resource priority, session duration
  • See all devices of a connected user (user_resources)
  • See all contacts of a user (get_roster)
  • See all MUCs (muc_online_rooms)
  • See all MUC options (get_room_options)
  • See all MUC affiliations (get_room_affiliations) like owner, admin, member, outcast, none
  • See all MUCs where a user is occupant (get_user_rooms)
  • Read content of vCards (get_vcard)
  • etc.

This shows that an admin can access most private data of users including their contact lists, their group memberships and other personal data like IP addresses, names, devices and so on. The admin doesn’t have to directly access the database or monitor traffic. He can just use ejabberdctl.

Feedback of our readers

Several readers mentioned that this test is true for all services that require servers.

It depends. Some services store your contacts and group memberships client-side and introduced other measures to hide this data from servers.

Test 3: Analyze the Mnesia database

We want to learn more about our users. Let’s analyze the database! By default, ejabberd uses Mnesia to store all data. An admin can simply enter sudo ejabberdctl dump dump.txt to dump the whole Mnesia database to dump.txt stored in the Mnesia folder. This file includes:

  • user-specific data for SCRAM-SHA-1 used for authentication (hashed password, salt, number of iterations)
  • user-specific key material (e.g. for OMEMO PreKeys)
  • PEP (Personal Eventing Protocol) information
  • last activity of users
  • private storage of users (bookmarks like saved MUCs)
  • all MUCs (members, options)
  • the same information accessible with ejabberdctl and more

Since most of it is stored in cleartext and the admin has direct access, he can read and change most of the values in the database.

Test 4: See content of messages and passwords in cleartext

So far, we didn’t read actual messages or passwords. This is also very easy. Just change the log level in ejabberd.yml to loglevel: 5 and restart the server! Now, the logging operates in debug mode which means that every message will be logged in ejabberd.log. This includes:

  • message metadata (message ID, from JID+client to JID, timestamp)
  • message content (if no encryption in use), may include images, files, location data, audio files
  • message status (received by a client, displayed (= read by) to a user)
  • client status (offline, online, typing)
  • non-public user actions (user changed avatar, status message, vCard information or created a private MUC)
  • passwords in cleartext even if SCRAM is enabled (every time users register a new account or change their password)
  • and more!
Cleartext passwords in ejabberd.log. Every time a user registers an account or changes his password, his password is logged (in-band registration is used in this example.
Cleartext passwords in ejabberd.log. Every time a user registers an account or changes his password, his password is logged (in-band registration is used in this example. (🔍 Zoom in)

Logging in debug mode basically logs every event. Combined with traffic data, an admin can monitor every single action of all users on the server. However, this not only includes users of this server but also users of other servers who are members in MUCs of this server or chat with people on this server.

Feedback of our readers

Some readers said that one can use OTR/OMEMO etc. to trust contacts and write private messages.

This is true, however, OTR/OMEMO etc. only protect the content of messages while metadata, status information, passwords and so on remain exposed in cleartext. Furthermore, there are some discussions on GitHub that put a question mark over the security of the OTR implementation in the Conversations client.

Test 5: Manipulate user data

Up to this point, the admin was somewhat passive in his actions. Let’s manipulate data now! We return to ejabberdctl to:

  • inject fake messages from arbitrary JIDs (send_message chat) even if these users aren’t on this server, see image below (Conversations shows these messages, Gajim ignores them until the sender JID of the message is in the user’s roster)
  • add arbitrary JIDs to a user’s contact list (add_rosteritem) or delete JIDs (delete_rosteritem)
  • arbitrarily change vCards of users (set_vcard)
  • invite users to MUCs (send_direct_invitation) and let them be owner (set_room_affiliation) while kicking the original owner (muc_unregister_nick) or make him member. Of course, admins can change all options of MUCs (change_room_option)
  • delete messages older than x days if not delivered (delete_old_messages)
  • and more
Conversations shows this faked message from snowden@nsa.gov (which can't be true since Mr. Snowden uses Signal!). Gajim only shows such messages after an admin added the fake sender to the user's contact list.
Conversations shows this faked message from snowden@nsa.gov (which can't be true since Mr. Snowden uses Signal!). Gajim only shows such messages after an admin added the fake sender to the user's contact list. (🔍 Zoom in)

This shows that the admin not only can read nearly everything but also manipulate data arbitrarily.

Lessons learned

This article clearly shows the problems of communication systems that rely on server-side management. XMPP heavily relies on the server side: groups, contacts, vCards are all managed by the server. The main problems are:

  • nearly everything is stored in cleartext on the server
  • OMEMO isn’t widespread while some clients dropped OTR which is somewhat awkward since this could force you to deactivate end-to-end encryption completely
  • even OMEMO and the Tor network provide little protection since most data remains unencrypted
  • your personal data is shared with other servers as soon as you chat with remote users or join remote MUCs which exposes your data to other admins
  • most of the admin’s actions are fully transparent which means that you can’t detect them as a user (e.g. you can’t check if an admin enabled the above-mentioned logging of every event including cleartext passwords)

Other messaging systems like peer-to-peer messengers (Briar, Jami), or Signal rely on client-side management: groups, contacts, vCards are managed by the locally installed client. This comes with new problems in some cases, for instance all members of a group have the same rights since there is no server to check different roles. However, client-side management hides most data and metadata from servers, and gives server-side parties considerably less information about you and your chat activities.

To mitigate the above-mentioned problems with XMPP, our clear recommendation is that you run your own XMPP server, or use one provided by close friends/family members. If you want to run your own XMPP server, have a look at the (incomplete) checklist below:

Be aware that any server-side party can still monitor data and metadata as shown before. You must continuously maintain and secure your own XMPP server.

Feedback of our readers

Some readers repeatedly told us that Signal is evil, centralized and we shouldn’t recommend it at all. Additionally, they say that Signal is neither available on F-Droid nor “free” software and its developers hate federation (and so on).

We discussed some of these points in our “Federation myths” article (esp. in myth 2 and 3). If you don’t like Signal, don’t use it. However, don’t try to force us to tell our readers your ideological beliefs. Thanks.

Follow us on Mastodon:


Your XMPP server admin can access nearly all of your personal data and tons of metadata in cleartext. He becomes even more powerful if he runs more than one XMPP server. You have to trust and hope that the admin doesn’t abuse this power and that appropriate security measures are in place so that no third party can access your data, too. Unfortunately, server breaches are neither rare nor uncommon nowadays. Interestingly, many XMPP servers seem to be run by people in the European Union but only a small fraction published an obligatory privacy policy.

Moreover, passive monitoring of the network traffic makes it easy to identify which IP addresses connect to a server as clients (port 5222) or as another XMPP server (port 5269). Client and server actually exchange several unencrypted XMPP messages before talking over TLS when you connect to a server. Server providers, your ISP and other parties can easily see whether you use a particular server for XMPP communication. To avoid this, you always have to use Tor which makes things more complicated.

Running your own XMPP server requires knowledge about server security, regular maintenance and knowledge about XMPP server software. You shouldn’t consider running your own server as a “fire and forget” activity. As soon as your server becomes federated and you start chatting with remote users and participate in remote MUCs, some of your data will be out of control again. Moreover, you have to sometimes cope with incompatible server and client software. Last October, Tor and privacy activist Moritz Bartl (Zwiebelfreunde e.V.) stated that it is easy for state actors to monitor XMPP traffic and identify all server users. Furthermore, he is convinced that most XMPP server and client software is more a leisure project than secure software.

Tested and written in collaboration with Thorsten.



  • Nov 2, 2018: Added and commented some feedback of our readers.
  • Aug 17, 2018: Added image showing cleartext passwords in ejabberd.log. Added information about Tor in the summary.

See also