Using Gajim Instead of Pidgin for More Secure OTR Chat

I’ve been using Pidgin as my chat client for many years. The one feature of Pidgin that I care about more than any other is that it supports Off-the-Record (OTR).

If you don’t know about OTR, it’s awesome. It lets you have end-to-end encrypted chat sessions with people so that only you and the person you’re chatting with can read the chat messages and all other parties—such as your chat server (often Google), your ISP, or anyone else eavesdropping on your—cannot. It also has cool features like forward secrecy that other cryptosystems like PGP don’t have. If you’ve ever been to a CryptoParty, setting up Pidgin and OTR and learning how to verify keys is always on the schedule.

As awesome as it is, Pidgin and the Pidgin OTR plugin have problems. They rely on the libraries libpurple, libotr and libxml which are massive, written in C/C++, and are littered with memory corruption bugs. In 2011 EFF started the Open Source Security Auditing project and fixed several bugs in Pidgin-related libraries, but that project was far from complete. Just look at Pidgin’s security advisory page to see how often Pidgin security bugs get fixed. It’s great that bugs are actively getting fixed in software that experts recommend activists to use, but who knows how many more bugs haven’t been reported to the developers and are actively in use compromising the computers of people who put in extra work to remain secure.

I recently discovered Gajim, a jabber client written in python. Gajim also has an OTR plugin, but rather than depending on the bug-riddled libotr it uses an implementation of OTR written completely in python with no C bindings.

Writing programs in Python is a lot safer than writing them in C. With python, developers don’t get direct access to allocate, overwrite, and free memory. Instead they just declare variables and the python interpreter and it’s garbage collector take care of the messy memory management logic. This means that bugs in a python implementation of jabber and OTR are less likely to lead to arbitrary code execution.

If someone sends you a malicious message that triggers a bug in Gajim or it’s OTR plugin, they’re much more likely to just crash the program than to take over your computer.

That said, I noticed that Gajim’s Wikipedia page says:

Despite being written in Python (and thus generally invulnerable to buffer overflow attacks), Gajim has a history of a critical vulnerabilities. Up until late 2011, it was possible to forge a link such that when a receiving Gajim user clicks on it, arbitrary code would be executed on the Gajim user’s machine.

As far as I know there hasn’t been a formal code review of Gajim. Just because there used to be an arbitrary code execution bug (that’s since been fixed) doesn’t mean that the project as a whole suffers from security problems.

I’ve only been using Gajim for two days now, but so far it seems great. After installing Gajim you need to click Edit, Plugins, and switch to the Available tab. From there you can download and install the Off-the-Record plugin. Back on the Installed tab you can click Configure to generate OTR keys for your accounts.

Gajim plugins

I haven’t looked in detail at the plugin installation mechanism for Gajim, so I don’t know if the download goes over HTTPS, or if the package is signed. I hope that both are true, but it’s quite possible that neither is.

Of course, when Windows users download Pidgin’s OTR plugin from, it’s never been over HTTPS and has never forced signature verification either. We need to work in this.

I generated a new OTR key when I started using Gajim. But since I’ve already verified OTR keys with dozens of people, and my OTR finerprint is even printed on my business card, I wanted to keep my old OTR key.

So I decided to write a Pidgin to Gajim conversion script called pidgin2gajim. If you too want to switch to Gajim but don’t want to give up your existing OTR key, hopefully this will be helpful.

I also posted a feature request on the pure-python-otr project to add an “Import From Pidgin” button to the Gajim OTR user interface, which will make this process much easier for users.

Update: After talking to some people it appears that libotr isn’t as bug-ridden as the other libraries that Pidgin depends on, libpurple and libxml2. I’m still glad there’s a native python implementation of OTR though.

11 thoughts on “Using Gajim Instead of Pidgin for More Secure OTR Chat

    1. micah Post author

      Actually it doesn’t look like it. At least, libxml2 isn’t a dependency.

      [micah@spock] ~$ apt-cache show gajim
      Package: gajim
      Version: 0.15.1-4
      Installed-Size: 13505
      Maintainer: Yann Leboulanger
      Architecture: all
      Depends: python (>= 2.6.6-7~), python-gtk2 (>= 2.22.0), dnsutils

  1. Paul

    I have the “Plugin Installer” plugin installed for updates over FTP and configured it to “use TLS transport” and with Wireshark i could see that they are using ProFTPd with TLS

  2. jooe

    Have been using gajim for a while after you suggestion.
    Two major concerns:
    – Logs cannot be completely deactivated – start and stop of each otr session are recorded. This is a serious issue to plausible deniability. Bug report:
    – When running in Windows 7, shutting down the computer causes incorrect shutdown of gajim. At restart, all gajim settings (accounts etc.) are lost.

    So I am returning to pidgin for now.

  3. Matt

    What’s the current state of OTR chat clients under linux? Is gajim still good to use, or are there better things out there?

  4. Pingback: [tecnota] Pidgin: alguns detalhes |

  5. Manuel

    Writing programs in Python is a lot safer than writing them in C? Not true. Python has eval, so there is your arbitrary code execution. (There seem to be people who try to write calculator web apps using eval, which is a bad idea.) Python programs need to abstain from eval (and probably a few other features as well) in order to be safe. This seems to be given for gajim-otr, though.


Leave a Reply

Your email address will not be published. Required fields are marked *