Gravacacher

Important: Brevity disclaimer.

Intro

When hosting personal blogs, forums and things like that it often becomes a problem to support user avatars - requiring user to register on your blog / forum and upload avatar may be too much for the stranger who just accidentaly entered your site to comment on something.

One of solutions for this problem is to use services such as gravatar.com which, being supported by site engine, allow users to enter just their e-mail or other identity information and based on that fetch their avatar from some centralized place.

This solution has very serious drawbacks, though:

  • It puts very high load on this centralized place.
  • It depends on centralized place accessibility - which often is a problem considering item one.

To partially overcome these problems, caching can be used, so that once fetched, avatars remain in cache for some reasonable period of time and, thus their availability does not depend on centralized place anymore.

As the task is quite specific, it’s not the best idea to use some general purpose HTTP caching software - you need some specialized code in order to do that.

There are several existing gravatar caching solutions available (try googling “gravatar cache” or something), but as usual, they do not satisfy me in one or another aspect, so I’ve written my own one

The name of caching server is Gravacacher. It is written in Ruby, the license is GPL.

Further information can be found in distribution, files INSTALL.txt and README.txt, here I quote only “features” and “security mechanism” paragraphs from README.txt for conveniense.

Features

Gravacacher has the following features:

  • Supports security mechanism to allow access only to those avatars your web software has generated links to, more on that below.
  • Supports multiple sites - I do not know any other service except gravatar.com at this moment, but it’s possible new ones could appear.
  • Supports “permanent” avatars, i.e. those that never expire - useful for your own avatars stored on your own web server.
  • Supports both positive and negative TTLs for cached avatars.
  • Supports “default” avatars fetching even if main server is down or overloaded - those fetched avatars will not be resized, though, so make sure the link points to the image of correct size.

Security mechanism explanation

The basic idea is to prevent others of using your gravacacher installation as free gravatar.com caching proxy for their own needs.

Leaving your avatars proxy open could not only cause unwanted system load and traffic, but also in the case of some error from gravatar.com or other server you could cache - for example, if the server you cache does not validate “default” parameter well enough - the unrestricted installation would in fact become open general-purpose HTTP proxy server, which is even more dangerous.

To overcome that the following is done:

  • Link generator (which is typically some blog / forum engine) besides of generating the usual set of parameters necessary for fetching the information from gravatar.com or other server, also generates MD5 hash of “password” + “parameters”, where “password” is known only to gravacacher and generator engine. This hash is appended to the set of parameters that are put in the link.
  • When serving request, gravacacher calculates MD5 hash of reveiver parameters (excluding the hash, of course) and compares it with the received hash. If these do not match - request is denied.

Here’s one simple example, using fake hashes / ids for clarity.

Suppose that the request we would normally generate is

http://www.gravatar.com/avatar.php?gravatar_id=12345&size=80& default=http%3A%2F%2Fwww.example.com%2Fdefault_image.png

Parameters here are “gravatar_id=12345&size=80& default=http%3A%2F%2Fwww.example.com%2Fdefault_image.png”

If password is “bla-bla-bla” and gravacacher installation is accessible as “www.example.com/gravacacher.fcgi” then the generating software should perform the following:

  • gravacacher_id = MD5("bla-bla-blagravatar_id=12345&size=80& default=http%3A%2F%2Fwww.example.com%2Fdefault_image.png")
  • Let gravacacher_id from the previous step be “67890”.Then we generate new URL by putting gravacacher_id there and replacing www.gravatar.com by gravacacher url resulting in the following url: http://www.example.com/gravacacher.fcgi?gravatar_id=12345&size=80& default=http%3A%2F%2Fwww.example.com%2Fdefault_image.png&gravacacher_id=67890

Please note that this feature does not prevent unauthorized retrieval of avatars from your cache that you generated links to - after all, it’s almost impossible to know if requester is the “valid” one - i.e. that one who just downloaded the page from your server and now asks for avatars by links from that page, unlike somebody who fetched the page some time ago and now repeatedly uses generated link to fetch the avatar over and over.

However, it does prevent others from using your cache to retrieve things you’ve never generated links to - and that, I beleive, should be enough for most people. If not, consider implementing some form of passwords rotation, so that the password used for generating links is changed once in a while, rendering all previous links invalid.

Finally, of course, if despite all dangers you want unrestricted access - you can turn security check off by specifying empty password in config and omitting gravacached_id from your links - then gravacacher will work in unrestricted mode.

Download

The latest version is 0.1_alpha, here are its sources.