Page 1 of 1

Securing Photos on Website

Posted: Tue Aug 30, 2005 7:07 am
by BZorch
How can I prevent just anyone who knows the url to my photos(jpegs) to download them without logging in? I know there has to be a simple way to secure them, but I have failed to find anything in this forum or on the web. From what I have been reading it would be inefficient to store them in a blob field in my database. Do I store them outside of the html directory? If so, how can my authorized users link to them? I am using sessions to authorize access to all other areas of the site. Any other ideas?

Thanks

Posted: Tue Aug 30, 2005 7:22 am
by vd
put your images outside of the document root.

save the file name in a datebase (together with the permissions)

put following example into "getfile.php"

Code: Select all

// ... here should stay your code to translate the posted image id into the internal file name

if (file_exists($_file_name)) {

	header("Content-type: ".$_file_type);
	header("Pragma: public");
	header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
	header("Content-Disposition: attachment; filename=\"".$_file_name."\"");
	header("Content-length: ".$_file_size);
	
	$_handle = fopen($_file_name, "rb");
	
	$_file_content = fread($_handle, $_file_name);
	
	echo $_file_content;
	
} else {
	
	header("Location: not_allowed.php"));	
	
}
write your html code and replace the file name within your image tag with "getfile.php?media_ID=37".

!!! Don't forget to validate the post

Posted: Wed Aug 31, 2005 6:29 am
by BZorch
Thank you for the response.

When you say translate the ID into the full name, I assume you mean to do a query on the database to pull entire address. The links to each photo are created dynamically from the users search, so I can either post the ID and search for the rest of the address or post almost everything in the address of the link (using a number of variables) in a different order with the exception of the main folder of the photos and combine/decipher it in the get.php script. Which way would you suggest? or is there an even better way?

I have been trying to figure out all of the header data that you have written. PHP.net is not that helpful and I am continuing to try an find something that explains each of the parameters in more detail. Is most of the header information place holders for me to fill in or do I use it word for word (I assume word for word since you said paste)? The one that is most confusing is Pragma: public. I would also assume besides validating the post. I would also validate the session variable to verify that the user does have permission.

Posted: Thu Sep 01, 2005 7:48 am
by vd
BZorch wrote:Which way would you suggest? or is there an even better way?
I would post the ID and then check for the rest in the db. If you post the filename it can be overwritten to something else. With the ID you have only to check if the person is allowed to open this special file.

I got some good examples of how using the header in http://www.php.net/manual/de/function.header.php (user comments).

Posted: Thu Sep 01, 2005 11:33 pm
by josh
If you are displaying the photo on a page using the img html tag, you could also have a token that is invalidated after the image is displayed once, that would prevent users from copy pasting a link to the photo to their friends, this approach could be taken if you didn't want to restrict a photo to members only, but still didn't want the image to be viewed outside of your web site / hotlinked. Optionally you could reference the photo not by id, but by the basename() of it's physical address on the filesystem, using that in conjunction with mod_rewrite would be an optimal solution.
http://example.com/photos/example.jpg would display your photo if the user is authed, or would return a 403 or display an 'error image' if the user does not have access.

Posted: Mon Sep 05, 2005 6:29 pm
by BZorch
Thanks. It may be dificult to display the physical address because the photo are organized in a number of folders. Using my test database all of the photos are in a single folder and this idea would work well in that situation.

I like the get.php script as long as my server can handle the load of a number of people clicking on each photo that is returned in the search. From my understanding from the previous post I will query the DB everytime some clicks on the thumbnail of the photo with its ID and then use the header() function to return the photo. This option does seem to be the most secure.