Visit my Flickr photo stream for more abstract eye candy.
In my earlier article, "Connecting Web Services: Inherently Insecure", I commented on the sad current state of security in connecting public web services like Flickr, del.icio.us, last.fm and others with specialized client software. In this article I'd like to make suggestions as to how this current situation could be improved. So as a follow-up to my complaint above, this is a proposal of a simple method to provide more secure web service client authentication that should adress most of my ealier criticism.
Let's start with a scenario that illustrates the situation. In the last article I used the dystopian example of a client software that secretly collects your login data and sends it to a remote server. This might seem an outlandish concept, yet it is still a real possibility. In this article I want to use an example that is even more rooted in the real world and which illustrates a more recent threat.
Let's say you have a website with a blog, and you use a plugin for your blog software that connects to your del.icio.us account and retrieves a couple of recent links and their tags to insert them into the page. This plugin needs to authenticate to the del.icio.us web service in order to fulfill its function; which usually means that you need to store the login data somewhere where the software can access it, maybe in a configuration file or in the code file of a script. These files are usually stored in a way that people can't simply read them from the outside.
What if there is a security breach on your site? Most people recognize that web servers are not as secure as they should be, and yet usually everybody just assumes that they won't be affected by this possibility. But the last year has clearly shown that as our server software grows both more complex and is becoming more and more widely used, the potential for vulnerabilities and abuse is growing. You don't have to look far to find exploits for popular Wiki systems that allow attackers to read any file on your server; and there is a growing number of automated worms that exploit phpBB vulnerabilities and allow the same kind of unlimited access to a web server's data. In short: the threat that somebody knowledgable enough can read the scripts and configuration files on your webserver is very real.
So imagine there is such a security breach on your site, and someone has had access to your passwords; and imagine you actually have realized this early enough, maybe by reading your server logs. What would you do next?
- You disable and/or patch your software. This is obvious and crucial.
- You evaluate the level of damage; among other things, this means determining the list of passwords that have potentially been collected and are from now on to be regarded insecure.
- You change all your passwords.
It's the last step that bugs me the most. I have to change my password to my del.icio.us bookmarks, and then modify all related scripts and re-configure all the client software I use with this service, just because of a phpBB vulnerability? And, maybe even worse: The attacker can now delete all my del.icio.us bookmarks and exchange them for links to his porn site, just because he has gotten ahold of the login used by a script that wouldn't even require write access in the first place?
We can do better than this. There are better ways to manage access to our data. We need a way to authenticate clients that does not involve giving out the master key. We need a solution where we can actually manage the services that we want to connect to, and not just blindly give away our master keys every time we want a shiny new gizmo on our site.
Why don't the service providers in question (Flickr, del.icio.us, ...) issue identification tokens which, in combination with the user name, are used to athenticate a client to the service? So that I, as a user, can create as many of these identification tokens as I require, one for each client that I wish to connect to the service?
Service providers should offer us a way to issue and manage these identification tokens: a way to create new tokens, to delete existing tokens, and to specify the application functions that can be accessed with such a token. So that a client doesn't automatically get root access to my data just becasue it wants to read some information; so that users can determine the level of access that a client has to the data when it connects to the service with a specific token; so that we can revoke tokens that have become insecure. So that a security breach on my website doesn't mean that my master password is now in the public domain.
There needs to be a way to revoke authentification tokens that have been issued at some point in the past. This might seem like a feature of negligible importance, but in reality I think it's the most important addition to the current state of client authentification, which is easily illustrated by the example of a hacked website, as described above.
And there needs to be a way to limit the amount of access that is linked to an authentification token. I can't see why an iPhoto plugin that allows me to upload photos to Flickr does this with a login that allows anybody who knows it to delete my photos. The software doesn't need this function of the web service; so why should we issue it with this level of access?
The Executive Summary
- The master password to a web service account should be used by the user, and by nobody else. Especially not by client software that connects to the service in question.
- Clients that connect to a web service should instead be issued authentification tokens that can be created by the user, and which are linked to his/her user account.
- The user should be able to determine the level of access that such an authentification token grants to the connecting client. Write access to a user's data should only be granted to clients that actually require it.
- A token should easily be revoked as soon as it has been proven insecure.
I don't think this is too much to ask. I'm surely not the first person to think of this, and I don't believe service providers don't use such a mechanism because they are lazy; I believe the lack of such a mechanism is more to be attributed to a desire of keeping the systems simple, so that there is a low level of entry for application developers to enhance the existing services with new clients. But I think that, as the amount of services that we use grows, we are approaching a point where we need to spend a little more attention to the way we handle access our data.
With such a system in place, I wouldn't be nervous to test out new clients to the services I use, because as I test a new client I could only allow it read access; and while such a system may seem to increase the work load for plugin developers a little, I actually believe it will help the growth of a stable web service ecosystem.
We don't want to teach novice users that it's OK to give out master passwords without giving it any thought. And we also want to make sure that there is enough trust in the system that a healthy experimentation can take place, without creating a situation where everybody stops using it because it's too risky; and without creating a situation where large-scale exploits abuse these wonderfully extensible systems. We need to ensure a minimum level of trust and security that allows us to try out new things every day without risking the loss of our most important data.