Situation: DrProject has a very useful timeline feature, which shows all the activity (tickets opened/closed, source control checkins, wiki edits, etc) relating to a project. To make things even better, there is also an option to export this feed as RSS (now, [this is also slightly broken], but that's another story).
Problem: If students are using DrProject to manage a marked project, there should be no way that students in one group can see the timeline another group. From the web interface, this is handled by the standard authentication mechanism... But there is no standard mechanism for authenticating RSS feeds. And, even if there was, students should not be giving their CDF passwords to online news reading services (both because the service might do Something Bad with it and because people should not be in the habit of giving out their credentials).
Current solution: Turn off RSS.
That's a really crappy solution.
What can be done?
Well, Andrew Louis and I were talking about it yesterday, and we were discussing a few of the different mechanisms used by similar web pages.
Flickr, for instance, assigns each user an arbitrary ID. After they register a name, there is no way to see this ID. If you manage to find a person's ID (either before they register a name or through some other means), there is nothing stopping your from taking a look at any of their feeds (take a look at the photos from my contacts!). Ok, so that's a pretty crummy solution.
Facebook is a bit more interesting. It assigns each feed a random ID. To view a feed, you need to know both the user's ID (easy to get) and the random ID (hard to get):
But this isn't quite good enough. If someone gets hold of the secret key, it's all over.
So what can we do?
Well, else can we use to tell the difference between you and me? What about the headers our newsreaders send? The IP block our request originates from? How frequently we check the feed?
Ok, so it might be tricky to implement a frequency-checking heuristic... But it would be easy to say "hhmm... Last time you checked this feed, you used Google Reader. But this time your User-agent tells me that you are curl. Something's up!"
When a user wants to read an RSS feed, they are given a URL with a unique key. The first time that feed is accessed, the User-agent string (and possibly other headers) are recorded. On subsequent requests, the values are compared and if there is a significant change (for some value of "significant")  and the old key will be invalidated. The legitimate user will be asked to re-validate the next time they download the feed.[/edit]
This will not make attacks impossible, but will certainly frustrate them, because the attacker must get the headers right on the first try.  If they get it wrong, they will have to wait for the legitimate user to get a new key, find that key, then try again. [/edit]
- What if someone checks their feed from both an online service (such as Google Reader) and a newsreader on their laptop?
They just generate two keys -- I don't see any reason that one user should not have more than one key associated with them.
- What if the headers change from less sinister actions?
No problem -- getting a new key will be a matter of a couple of clicks.
- But doesn't that mean all the old items will be marked unread?
Yes. Is there a way to fix that?
- Isn't there still a possibility of attack?
Yes, it is possible. But, hopefully, it will be hard enough to thwart casual attackers.
So, any comments?
Postscript 0: What about OpenID?
It looks really neat. In theory, it would solve this problem. In practice, though, there are two issues:
- Added complexity -- we would either have to build an OpenID server into DrP or rely on an external server.
- Limited support -- at the moment, only a handful of readers have support for OpenID (Google Reader being, I believe, a notable exception)... And we don't quite have the market share to change that. At least not yet