XMPP IoT Anti-Patterns

Posted on July 4, 2016
Tags: xmpp

The recent issue (2016-14 page 78 ff.) of the German computer magazine c’t has an interesting article about security issues in alarm systems. I was a bit surprised that in 2016 we still have systems online which are vulnerable because of a default password or passwords like ‘1234’. The c’t had articles about similar issues before. Obviously the industry has much to learn about securing the Internet of Things (IoT).

What caught my attention was an XMPP message that is, according to the article, used by the alarm system to confirm the user PIN with a central server in order to disarm the system. The article describes a security flaw where sending the same message without the PIN would erroneously disarm the system. The message stanza looks like this

<message
  id="n0000-000000"
  to="<unique-id-of-alarm-system-central>@climax-home-portal"
  type="chat"
  from="security_ admin@climax-home-portal/Smack">
    <body> 4150795OqiESNX2RCHC/ :;MODA:1,0, 1234 </body>
</message>

This demonstrates nicely a few XMPP-for-IoT Anti-Patterns I’d like to discuss.

The Anti-Patterns

  1. Using XMPP without properly secured TLS. What made it easy to have a direct look at the used XMPP stanzas, was that the alarm system used an unencrypted connection. This revealed the PIN position and made it possible to inject spoofed stanzas.

  2. Abusing <body/> to carry machine data. RFC 6121 § 5.2.3 defines the <body/> content as “human-readable XML character data”. I guess this contributed a bit to the security flaw, where a message stanza without the PIN would disarm the system, because parsing that particular body content format doesn’t seem easy. But even if my guess is wrong, abusing the <body/> element in such a way will eventually snap back to you once your IoT environment grows.

  3. Allowing the client to determine the resource. Depending on the services policy on resource conflicts, this could lead to reconnect loops until the old connection using the same resource finally timeouts. Hardcoded resource strings also make it easy for an attacker to guess a resource. If the client does not protect itself against unsolicited stanzas send, e.g. by using XEP-0016 Privacy Lists, then this could at least allow an attacker to drain a mobile clients battery or allow him to access unprotected IQ interfaces.

  4. Using ‘chat’ type messages. Often done because “we don’t know better”. OK, I’m just guessing that ‘chat’ was used because of this reason. But I see it often that people just use ‘chat’ for no obvious reason, ‘normal’ would be the better choice in this case. And since it is the default type, you can omit it, saving a few bytes over the wire.

The Correct Patterns

  1. Use proper TLS for god’s sake. But “enabling” TLS is not enough. There is an intolerably large amount of implementations using TLS with an “accept all certificates” policy in order to be able to connect to hosts with self-signed certificates. That is a very bad approach in every aspect. Instead, use Certificate Pinning. With Java Pinning and Smack, TLS Certificate Pinning is as easy as:
SSLContext sc = Java7Pinning
  .forPin("SHA256:e3b1812d945da1a2a2c5fa28029d2fe34c7c...");
XMPPTCPConnectionConfiguration conf = XMPPTCPConnectionConfiguration
  .builder()
  .setUsernameAndPassword("user", "pass")
  .setXmppDomain("example.org")
  .setCustomSSLContext(sc)
  .build();
  1. Use a custom extension element for your data. After all, extensibility is one of the strong arguments for XMPP. All XMPP libraries provide APIs to handle (create, process, serialize, deserialize) custom extension elements. The message above could for example look like this if they had used a custom <disarm xmlns='namespace:of:vendor'/> extension element:
<message
  id="n0000-000000"
  to="<unique-id-of-alarm-system-central>@climax-home-portal"
  from="security_ admin@climax-home-portal/ba7971ca-a887-404b-8c48">
    <disarm xmlns='namespace:of:vendor'>
      <data>4150795OqiESNX2RCHC/</data>
	  <mode foo='true' bare='false'>MODA</mode>
	  <pin>1234</pin>
    </disarm>
</message>
  1. Let the server assign a resource. You usually want to do this independently of your use-case for XMPP (e.g. also when using XMPP for Instant Messaging). Since this is not IoT specific, but true for general XMPP usage, the XMPP Wiki also mentions this as guideline for IM developers also providing a rationale.

  2. Use a fitting message type. XMPP provides a variety of message types, each with different semantics. Sadly those types are named after their common use-case and not after their semantic, so people assume that they are just useful for that. For example ‘chat’ for chatting purposes and ‘headline’ for headlines. But in the end, you should choose the message type depending on your use-case. Primarily the message type affects the routing rules of the message stanzas. There is no reason you would want to use ‘chat’ in IoT. Use ‘normal’ and omit the ‘type’ attribute completely, since ‘normal’ is the default. Messages of type ‘headline’ also provide some nice properties for the IoT use-case (fan-out to all available resources of the recipient).

Remark

Note that this list of patterns is not comprehensive. Also some points are not exclusive to XMPP-for-IoT, but apply to XMPP usage in general.

Get in touch with the XMPP Community

I really encourage vendors to discuss their ideas, designs and approaches build upon XMPP with the XMPP community. I have encountered a lot of IoT specifications and implementations using XMPP which had, not only minor, but also serious design flaws. Fixing the ones which are already in production is an enormous effort. Thus I can only strongly recommend to get a peer review for your design early.

The XMPP community is very friendly, especially when it comes to supporting open standards and potentially subsequent open-source implementations. Usually you will find people willing to help you design and review your XMPP usage. Just join the xsf@muc.xmpp.org chat or post your XMPP related questions to the standards@mail.jabber.org mailing list.