Chatterbox Part 3 — Security and mobile devices

This is the third part of the Chatterbox series. For your convenience you can find other parts in the table of contents in Part 1 – Origins

What do we do about mobile devices? Depending on which platform we chose in previous part, we may have very limited options. If we go with our custom UI, we may need to implement something. For emails it’s relatively simple — there are plenty of clients out there. Similarly for IRC server. And for Slack-like chats there typically is some mobile app provided.

However, there is a big question here — if we decided to go with Slack, how do we make sure our messages are safe and encrypted?

Problem

If we go with Slack-like solution, we can easily push messages using CLI, REST API, webhooks etc. But if we just push plaintext then we have a very serious issue to solve. Apart from not trusting the underlying network, we now have another component which can leak data, spy on us, or simply expose something publicly. It may be okay if we generally don’t care, but once we take it for serious we need to have some good solution in place.

We could go with something built on top of the IM. Take Keybase or any other GPG based solution, generate keys, and send encrypted messages. But this effectively turns whole communication upside down, and your other side must be aware of it. Something we don’t necessarily want to do.

Solution

So we need to implement encryption. I’m not going to tell you how to do it (there are plenty of tutorials out there), just keep these things in mind:

  • You WILL HAVE TO be able to rotate keys sooner or later
  • You probably want to have backwards compatible solution (for changing algorithm, keys etc)
  • Once you start encrypting messages, it makes it much more error prone — think of unicode characters etc. You’ll need to go with BASE64 or similar, but then your messages will be much longer

Web interfaces

Now, let’s say that we push encrypted messages to Slack-like platform. What do we do next? We need to decrypt them on our side when reading.

For web interfaces this is relatively simple. Just inject some JS decrypting things on the fly. You need to figure out how to maintain keys, also, inlining JS may be disallowed depending on same origin policy. However, it is relatively straightforward.

For desktop applications with webview, you may need to use custom proxy to drop some HSTS-like headers etc. Nothing big but this may decrease your performance.

Also, keep in mind some messages may still need to go in plaintext. For instance links, link preview feature may be implemented on a server side of the chat platform, so if you want to have preview, you’ll need to decrypt them before pushing.

Mobile apps

Things here get even trickier. Some platforms will not have open source clients. You may still modify them on a binary level (with smali for Android for instance) but then you have to kind of maintain them. It may be much harder for iOS vs Android vs other platforms. Still, this is worth doing because it typically gives much better UI than web browser on mobile phone.

Security is also important here. You need to keep mobile apps up to date, so you need to be able to reapply your changes easily. Forking the repository works but how often do you want to go and solve merge conflicts?