• PHP Help
  • I have a web site which publishes pictures

OK.. So here is my problem.... I have a web site which publishes pictures (about 10,000 to 40,000) (and no they aren't porn)... The files are stored in a single directory, (or maybe a tree structure of directories) I only want people to access the files via the web pages, and not by browsing directly to the indivdual pictures, if they know the name of the file (maybe from a prior visit or by interpolation) they have access to it.... How do I prevent this... Here are some thoughts.... (BTW, I'm using sessions to maintain security to the actual web pages not 404 Authorization)

    Put the actual image files outside of the web-accessible directory, then use a PHP (or whatever) file-server endpoint to output the image, with whatever user access restrictions you want to impose on it. (So your image tags might have something like src="https://example.com/image?name=my_image.jpg" -- or a more RESTful URL if you prefer.)

    NogDog's suggestion is a good one -- if you put the image files outside of your publicly accessible HTML directory (aka "web root") then you can prevent direct access to the image files and force visitors to visit a PHP page to gain access to the image files. However, you would still need to construct your PHP logic to enforce things. For example, what would prevent a user from copying the PHP url used to display a particular image and just visiting that PHP page directly? You might want your PHP script to:
    + check the http_referer value
    + check the visitor's $_SESSION for some kind of token that changes frequently
    + block bots or user agents that look like bots

    17 days later

    Sneakyimp, that's an excellent insight. However, rather than checking all those, wouldn't it be possible to compare REQUEST_URI to PHP_SELF and, if they're the same, show an error instead of the image?

    dalecosp

    I think that depends on how secure you want it, since HTTP headers in general can be spoofed. I.e.: are you just generally trying to prevent casual/general hot-linking, or do you want to validate that the user is currently logged in? (Or is there some middle ground?) Since the OP said, "BTW, I'm using sessions to maintain security to the actual web pages," I would guess some actual $_SESSION check would be in order?

      Following on from NogDog's suggestion: if the images are stored outside the site root then they won't be accessible by any URL except that of the page that is supposed to be serving them; that works for the image itself as well as the page it's displayed in.

      Configure the web server so that the URL for the image looks like the URL for an image instead of a script. Say the request sent by the client is for http://www.example.com/gallery/honestly-not-porn.jpeg. The server rewrites that to http://www.example.com/gallery-script.php?filename=honestly-not-porn.jpeg. gallery-script.php would do all the suggested checks for session/cookie values, before sending suitable response headers (including but not limited to cache/cookie control, Content-type:image/jpeg and Content-length:<?=filesize($image_path);?>) and then dump the image data into the response with readfile($image_path);

      An illegitimate request could get a 404 or 403 response or some fallback image depending on what you think would be appropriate. It should go without saying that the name given in the URL need have nothing to do with the name of the file on disk, provided you have a reliable mapping between them. Indeed, if you have sessions then you can store that mapping in the session data and generate it afresh (with new URLs) for each session. That is, if you don't mind users seeing different URLs for the same images on different visits.

        Write a Reply...