3

I have a folder named - Images. This folder contains user profile pictures. Right now a user can see his image by just copying the image URL to his browser any time. This way he can also see other user's profile pics. What I want to achieve is - The user should be able to see his profile pic only through the PHP page on my website. If the user directly puts the image URL, it should not be displayed.

I tried to achieve this using .htaccess. This is what I have in the .htaccess file :

RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?mysite.com/
RewriteRule \.(gif|jpg)$ http://www.mysite.com/errorpost.jpg [R,L]

I am new to .htaccess. If there is a way to achieve this, please help.

Thanks in advance.

Anoop Nair
  • 171
  • 1
  • 2
  • 13
  • The above method I used is not working. It still displays the image when the image url is typed. – Anoop Nair Dec 01 '12 at 11:32
  • What is the problem you wish to solve. Do you want to prevent people from viewing profile images of profiles, they are not allowed to see? – Gerben Dec 01 '12 at 18:25
  • @Gerben .. Suppose I am looking into my profile. I can see the image location of my profile pic by looking into the source code. Then I paste that url to the address bar and the image opens up. Now I want that the user should not be able to access the images directly this way. Is it possible to restrict the user from viewing the images directly. He should be allowed to see the image just using the PHP page i have created as the profile page. This way he won't be able to guess the url of other users and won't be able to see their images. – Anoop Nair Dec 02 '12 at 05:21
  • 1
    Generation pseudo-random filenames for profile images should solve this. e.g. using the md5 of the profile id, as the image filename. – Gerben Dec 02 '12 at 12:11

1 Answers1

3

I have the same problem. Currently I found 2 ways:

1) base64_encode() + ajax + js/jquery

  • Store every image encoded by base64_encode() in binary file or database OUTSIDE www folder.
  • Use ajax to get that data. it should return "data:image/jpeg;base64,$enc_imgbinary"
  • Replace 'src' of 'img' attribute with returned result using js/jquery

pros

  • impossible to access image with direct link

cons

  • I did found not similar solution for video.
  • images should be encoded beforehand (or first usage) to minimize server CPU usage.
  • encoded images takes about 30% more space on disk => 1.3x disk space
  • if you want to keep original images on server => 2.3x disk space.
  • ~30% more data will be send over the network

2) long-random-names (+symlinks)

A) Store images in www folder using long-random names
B) Store images outside www folder with symlinks to www folder. (images outside www can also work as your desktop images backup)

notes:

  • folders must also contain random symbols
  • use '.' before any folder or file name => just in case, to prevent from displaying folder content on unconfigured apache
  • configure apache to folow symlinks in case B) (add FlowSymlinks to httpd.conf)
  • configure apache to prevent folder content listing (remove Indexes from httpd.conf)
  • example of image hierarchy:

    • www
      • .media_jmdue7jed
        • .user1_hash_!sdfsewewfsdfsds
          • .album1_name_!jfie8e7y77667fef
            • .photo1_name_!kjio9i890v8fsd978fyreshf
            • .photo2_name_!09098dfuujdsif87s7ysdffd
            • ...
          • .album2_name_!ghhyuflp!huidfjh
            • .photo1_name_!feojihudhufuuhfrufhi8484
            • .photo2_name_!2344gfdgfdgdfefedw232sdg
            • ...
        • .user1_hash_!j333re89dsfdsf
          • ...

pros:

  • Can be used for video also
  • You can still keep original images with original names outside www folder by creating symlinks to www folder using long-random-names. Even different for every user.
  • Image can be used outside your server (in forums, quick send direct link to your friend or similar)

cons

  • symlinks must be created beforehand (or on-fly)
  • Image can be accessed with direct link
    • however its nearly imposible to guess it
    • also you can change symlink random-name periodicaly or on image rights change (I quess google+ does so)
  • map original-name → long-random-name should be stored in db (or sidecard/meta file)
    • (can be bypassed if you keep original-name inside long-random-name by encoding/decoding or by combining original-name + long-random-name)

=====================================

I had implemented case 1) and it worked for me fine, however I did not found similar solution for HTML5 video.

Case 2) seems more flexible. However I still not sure about security. If anyone sees security holes please let me know.

gds
  • 31
  • 1
  • 3