Search code examples
phpjqueryimageurlindirection

Monitor image access AND/OR prevent direct access


I want users to see an image as part of a web page but I want to avoid them accessing a image directly. This could, say, give clues in the URL about what user they're linked to (a flaw I've seen in one facebook application).

How can I go about monitoring image access and/or preventing direct access to images (through url rewriting for example...)?

Solutions suggested so far:

  • Use of headers (reliable?)
  • Making access to images more difficult (ex: set image as div background).
  • ...

Solution

  • There is not bullet proof way. However, you can use heuristics. Inspect the following headers:

    1. Referer -- this header will be present is the image was requested by the browser as a result of <img> tag or CSS. This header will be empty if the image was requested directly (by typing the URL in address bar). If this header contains another domain then that other website hot-linked your image. Note that this is the expected behavior but it is not guaranteed that every browser will behave this way.

    2. Accept -- this header will contain a string such as image/* when image was requested because browser found it embedded in HTML tags or CSS. When someone requests the image directly by typing in the browser, you'll find values such as text/html,application/xhtml+xml etc. This is because browser does not know what to expect when it requests http://website.com/someimage.jpg; hence it will preferably ask for text/html content.

    In Apache, you can check (and match) HTTP headers to determine whether content is accessible or not. I am not sure about other platforms, but you can write a generic proxy script for serving images.

    Edit

    If the image URL reveals information that you do not want disclosed, you can obfuscate it by using hashes or encryption. So instead of serving content such as:

    <img src="/images/users/12345.jpg">
    

    You will write:

    <img src="/images/users/image.php?hash=<?php echo md5('secret' . '12345'); ?>">
    

    You'll need to write a script that sends the corresponding image to the browser.