Modernizing XMPP authentication and authorization
We’re excited to announce that we have received funding, from the EU’s NGI Assure via the NLnet Foundation, to work on some important enhancements to Prosody and XMPP. Our work will be focusing on XMPP authentication and authorization, and bringing it up to date with current and emerging best practices.
What kind of changes are we talking about? Well, there are a few aspects we are planning to work on. Let’s start with “authentication” - that is, how you prove to the server that you are who you claim to be. We’ll skim the surface of some of the technologies used, but this post won’t descend too deep for most people to follow along.
Authentication
Traditionally, authentication is accomplished by providing a password to your client app. XMPP uses a standard authentication protocol known as the “Simple Authentication and Security Layer” (SASL), which in turn is a framework of different authentication methods it calls “mechanisms”. Most XMPP services use the SCRAM family of mechanisms. In fact, it’s mandatory for modern XMPP software to support SCRAM.
These SCRAM mechanisms are quite clever: they allow both the server and the client to store a hash instead of the password, allow the server to verify the client knows the password, and allow the client to verify that the server knows the password (and isn’t just faking success - such as an attacker might try to do if they managed to compromise the server’s TLS certificate and wanted to intercept your traffic).
Yet, as far as we have come with password authentication, there are some real-world problems with passwords that we need to recognize. Passwords have proven, time and time again, to be a weak point in account security. From users choosing weak passwords, reusing them across multiple services, or accidentally exposing them to fake services (phishing attacks), there are multiple ways that unauthorized parties can gain access to password-based services.
Multi-factor authentication
To try and plug the holes in this leaky boat, many online services have adopted multi-factor authentication (“MFA”). This extra layer of security generally requires you to provide proof that you also possess an additional secret securely generated by the service. This is achieved using hardware tokens, mobile apps and often simply sending a numeric code via SMS. Using this extra step ensures accounts can still be protected even if passwords are guessed or obtained by attackers.
Most XMPP services and software do not currently support multi-factor authentication. If you’re a security-aware individual, that’s not a major problem in itself: you can achieve practically equivalent security by using a strong unique password and only using it to access your XMPP account. But as a service provider, you know that’s not going to be the case across all your users. As XMPP continues to gain adoption with non-technical users through new projects such as Snikket, we need to provide the safest environment we can for everyone.
Although we have had some hacky solutions available for multi-factor authentication with Prosody for a long time, there has been no standard approach implemented in clients and servers. The most recent and promising standard is XEP-0388: Extensible SASL Profile, which defines a way for the server to ask the client to perform more steps (such as prompting the user to provide a second factor) after authentication.
There are no known open-source implementations of XEP-0388 currently, but we plan to add support for it in Prosody as part of this project. Once this is in place, clients will be able to start introducing support for it too.
One of the challenges for multi-factor authentication in XMPP is that you don’t necessarily want to enter an authentication code every time your app connects to your account. With most people using XMPP on mobile networks these days, it’s common for your XMPP app to re-authenticate to the server multiple times per day due to network changes. You don’t really want to miss messages because the app was waiting for you to enter an auth code!
On websites, you generally provide a password once, when you initially log in. If successfully verified, the website then stores a cookie in your browser. This cookie is very similar to a temporary, unique and session-specific password, which is used to identify you from then on (which is why your account password isn’t required on every page request).
XMPP doesn’t have anything like cookies, so when a verified device reconnects, it will just use the password again. The server (if multi-factor is enforced) will inconveniently require the user to provide a second factor again too. There are some proposed to solutions, such as the CLIENT-KEY SASL mechanism by Dave Cridland. TLS client certificates are also supported in XMPP, and would provide a solution to this issue too. Usage of CLIENT-KEY in XMPP is described in XEP-0399, and time-based MFA authentication codes (TOTP) in XEP-0400, however neither are available in current XMPP clients and servers.
During this project, we plan to expand and implement these XEPs in Prosody, to make multi-factor authentication practical and user-friendly.
Authorization
Once Prosody has securely proven that you are the account owner, that’s often the end of the story - today. However, with the mechanisms that we just discussed that allow us to securely identify individual clients, we can start to do more interesting things. For example, Prosody will be able to show you exactly what clients are currently authorized on your account. If a device gets lost or stolen, it becomes possible to selectively revoke that device’s authorization.
As well as revoking access, we’ll be able to assign different permission levels for each of your sessions even if the device isn’t compromised. For example, maybe you want to connect from a client on an untrusted machine - but you don’t want it to have access to read past messages from your archive. That’s something we will be able to arrange.
Combining the ability to revoke sessions and the ability to specify per-session permissions leads us to another new possibility: granting others limited access to your account.
For example, Movim is a popular social web XMPP client. Anyone with an XMPP account can log in to a Movim instance, and use it to chat, follow news, and discover communities. One problem is that Movim needs to log in to your account, so it needs your credentials. That’s no so bad if you are self-hosting Movim, or you are using an instance managed by your XMPP provider. However, many people don’t have that option, and rely on third-party hosted Movim instances to sign in.
You might also want to connect other special-purpose clients to your account, for account backup and migration, bots, or apps that integrate with XMPP for synchronization and collaboration.
Using our new authorization capabilities, one of our big goals is to allow you to log in to such third-party apps and utilities without ever sharing your password with them. And when you are finished, you can easily revoke their access to your account without needing to reset and change your password across all your other clients.
Flexible permissions framework
Internally, we’ll support these new authorization possibilities through an overhaul of Prosody’s permission handling. In 0.12 and earlier, the only permission check supported in most of Prosody is: “is this user an admin?”. We are adding support for arbitrary roles, and allowing you to fully customize the permissions associated with each role. Users and even individual sessions can be assigned roles.
That means someone who generally has admin access to Prosody may choose not to grant that level of access to all their clients. Or they might choose to enable their admin powers only when they need them, spending most of their time as a normal user.
These changes alone will unlock many new possibilities for operators and developers. Expect the first pieces of this work to land in Prosody trunk nightly builds very soon, as it forms the basis of all the rest of the features discussed in this post!
Further updates about this project will be posted on this blog. The project homepage is over at modernxmpp.org.
About
Prosody is a lightweight and flexible XMPP server designed with ease-of-use and extensibility in mind.