Lucien Dubois
Lucien Dubois

Reputation: 1694

Protect images through .htaccess and PHP

I would like to check if users are logged in to access image files. Images would have this form

https://domain.com/folders/imagename.jpg

I tried this in the .htaccess:

RewriteEngine On
RewriteCond %{REQUEST_URI}\.jpg
RewriteRule ^(.*)\.jpg$ /protect.php

And this in my protect.php file

<?php 
if(rcp_is_active()){
   header('Content-Type: image/jpg');
   readfile($imageurl);
}
else{
   readfile("https://placeholdit.imgix.net/~text?txtsize=38&txt=Forbidden&w=400&h=400")
}
?>

My question:

Upvotes: 1

Views: 939

Answers (1)

MrTux
MrTux

Reputation: 34003

Update your .htaccess RewriteRule to pass the matched filename to the PHP script as follows (your RewriteCondition is superfluous):

RewriteEngine On
RewriteRule ^((.*)\.jpg)$ /protect.php/$1

Then you can access the passes value using $_SERVER['PATH_INFO'] or $_SERVER['PATH_TRANSLATED'] (then Apache tries to map it to the real path according to document root, see mod_cgi and RFC 3875 for more information about this). For this to work AcceptPathInfo needs to be enabled in Apache httpd (the default).

or use

RewriteRule ^((.*)\.jpg)$ /protect.php?filename=$1

and use $_GET['filename']. Especially here, beware for directory traversal attacks (e.g., someone uses /protect.php?filename=../../someother-file.jpg). I usually apply realpath to normalize the path and check that it starts with the folder which contains the files or the document root ($_SERVER['DOCUMENT_ROOT']).

In both cases also make sure you only deliver allowed files (e.g., what happens if an attacker uses /protect.php/protect.php). This might leak sensitive data.

PS: Maybe you also want to make the response non-cacheable or provide a Content-Length.

PSS: Even for the forbidden case you also need to provide a proper Content-Type - or use a redirect (header('Status: 302'); and header("Location: https://placeholdit.imgix.net/~text?txtsize=38&txt=Forbidden&w=400&h=400");) so that you don't need to re-request that image again and again.

Upvotes: 2

Related Questions