I have a social network where users can create posts with embedded images. The images are stored outside the document root. When a page is requested for viewing I want to send a normal HTML response with <img> elements that have an src attribute. The problem is, how to efficiently protect the images so that only authorised users can view them?
The permissions system behind the network is quite complex. The social graph has several different types of nodes and edges, and a user's permission to browse content depends on this graph. I consult the user's subgraph once on each page request, to retrieve a list of permitted content, but I don't want to have to consult it again for each image. It's an expensive exercise and some pages may have 50 or more images.
So, as far as I can see, when I serve the page I will need to send a key (or keys) which, when combined with data by the server, will 'unlock' the image. Here's an example of what I mean - in the example I am putting a key in an url, where the url is the src attribute of an image:
In this implementation I pass a parameter that uniquely identifies the image. I need to do this since I don't want to get in to translation tables, or user-specific translation tables (because of complexity and performance). I also send an 'image key'.
My idea is that the user's session will include a 'session key'. When the server receives a GET for an image, it will add the session key to the image filename requested and hash them (just like password + salt). If the result of the hash equals the image key, I'll retrieve the image from disk and send it.
The problem with this is that if a hacker gets hold of an image url, they have one input to the hash (ie. the image key), and the required output of the hash (ie. the image file name), so they could (using rainbow tables) work backwards to get a list of potential session keys. Then, through a series of requests and a process of elimination, they could establish the exact session key.
So, how do I get around this? I could change the session key with each request, but that would mean that image urls would change with each request, so there will be no image caching.
I'm sure I'm not the first to have this problem. Is there a 'common' approach to the problem? (I can't find such a thing). I could consider base64 encoding the images in the page response, but I'm guessing that would come at a performance cost.
FYI - I'm using PHP and Apache. I'd use url rewriting to tidy things up a bit.
Aucun commentaire:
Enregistrer un commentaire