uzzikie has asked for the wisdom of the Perl Monks concerning the following question:

fellow monks!

how can i use a CGI script to protect images from public access?
if someone knows the URL of the image, he can view or download it
so i hope to implement a method whereby only authorised members can view it
(what authorised members do with it afterward --copy, edit etc doesn't matter)
I have seen certain sites like photos.yahoo.com implementing this.
They generally append a session string behind the image like

http://somewhere.com/images/sample.jpg?abcdefg

hence, if u try accessing it by typing the URL alone http://somewhere.com/images/sample.jpg,
you will get a permisson denied error.

any leads are appreciated...thanks

Replies are listed 'Best First'.
Re: restricting public access to images
by dws (Chancellor) on Oct 08, 2002 at 02:49 UTC
    how can i use a CGI script to protect images from public access?

    You have a couple of options: If you're using Apache, you can put HTML pages and the images they reference into a directory that you've set up to require basic authorization.

    Or, you could use a CGI that checks for a cookie (that only your authorized users gets). If the right cookie is present, the CGI prints the correct response header, and then opens the image (which resides in some sekret location) and prints it. (If you're on win32, be sure to do binmode(STDOUT) first.)

      I'd hope you'd look to your httpd first to handle this sort of access control. Apache's .htaccess files my fav way to keep people where they should be.
      AuthType Basic AuthName "Squid User Access Reports" AuthUserFile /usr/local/apache/conf/passwords <Limit GET POST> order deny,allow deny from none allow from all require valid-user </Limit>
      Which is sloppy in some ways , this could certainly be more secure, giving your cgi carte-blanche to send users hither and thither IMHO is pleading for trouble. Doing this kind of ACL on an image by image basis ... would be pretty tricky though. Other things I've seen done , serialize your imagenames to death when they're created - so folks aren't able to guess them. Getting off topic now. bad karma. --shout down now!
Re: restricting public access to images
by robartes (Priest) on Oct 08, 2002 at 06:33 UTC
    Hi uzzikie,

    the answer is in your question :). You could write a CGI script that takes two parameters as input: the resource to get (e.g. sample.jpg) and a passcode of some sort (e.g. abcdefg). Your passcode could for example be based on the date, based on the user session (identified by a cookie sent earlier), on the number of camels that fit through the eye of a needle on any given day etc. The idea is that you only get the passcode if you access the image through a link somewhere else on your website. This requires that the rest of your website is somewhat dynamic, as it needs to generate (correct) passcodes on the fly.

    To actually protect your resources from direct access, you have to intercept the URL's and rewrite them to use your CGI script. If you are using Apache, you can do this with its URL rewriting engine. You'd have to rewrite http://a.com/camel.jpg?42 to http://a.com/cgi-bin/camel_keeper.cgi?camel.jpg&42 or something like that. camel_keeper.cgi is the cgi script described above. For more information on Apache and URL rewriting, visit the Apache documentation site.

    So, to summarise, you need to:

    * come up with a system to generate non-trivial passcodes

    * Rewrite your site in a dynamic fashion so it generates those passcodes in it's links to internal resources

    * Write a script that checks the passcode on resource access

    * Put in a URL rewriting rule to make sure all resource requests pass through your script

    CU
    Robartes-