Page 1 of 1

Secure image downloads

Posted: Wed May 31, 2006 3:53 pm
by pickle
Hi all,

I've got an interesting problem that I'm hoping someone has solved before ;) I'm working on an online image gallery. This gallery is viewable from the web, but requires a person to login (which therefore creates a session for them & stores the session & their timeout in a DB. To secure a page, all I need to do is include a file, and it automatically checks session timeouts and permissions).

The trick come when trying to secure the images. I pretty much have to put the images outside of the web root and then use a PHP file to load them into a webpage using:

Code: Select all

<img src = "image.php?user=username" />
I'm pretty sure I can't use .htaccess files & leave the images in the web root because I have no way of tying my authentication scheme into .htaccess sessions.

In my image.php file, I've put the code in that checks the DB to see if a user is authenticated. This effectively requires that a person be logged in to view an image. Unfortunately, it has to do this check every time. If I didn't do this check in image.php, then someone could just type in https://www.domain.com/system/image.php?user=joe and BOOM - they're in.

Unfortunately, after doing some testing, I've found (not surprisingly) that adding this database-permissions check makes the page load in 12.5 seconds vs. 0.25 seconds without the check (the times are totally dependant on the number of images in the page, but these numbers give you a relative idea).

Does anyone have any idea how I could speed this up? Ideally I'd like it to take the 0.25 seconds while still being secure, but 12.5 seconds for 27 images seems a bit excessive.

Thanks for any and all ideas.

Posted: Wed May 31, 2006 4:19 pm
by Todd_Z
What method are you using for the php file to view the images?

for example,

Code: Select all

$img = imagecreatefrompng( 'blah/blah/blah.png' );
header( "Content-Type: image/png" );
imagepng( $img );
is MUCH slower than

Code: Select all

header( "Content-Type: image/png" );
readfile( 'blah/blah/blah.png' );
If you aren't manipulating the images, there would be no reason to create a gd object.

Re: Secure image downloads

Posted: Wed May 31, 2006 4:44 pm
by Christopher
pickle wrote:Unfortunately, after doing some testing, I've found (not surprisingly) that adding this database-permissions check makes the page load in 12.5 seconds vs. 0.25 seconds without the check (the times are totally dependant on the number of images in the page, but these numbers give you a relative idea).
It sounds like the problem is having to go back to the database for every request. One solution would be to use file based sessions which are usually faster. Once a user is authenticated via a database check of their credentials, some minimal user data is stored in the session. From that point forward your included script that controls access to the pages only needs to check a couple of session vars to authorize access.

Posted: Wed May 31, 2006 5:11 pm
by pickle
Todd_Z wrote:What method are you using for the php file to view the images?
The second one:

Code: Select all

header( "Content-Type: image/png" );
readfile( 'blah/blah/blah.png' );
arborint wrote:It sounds like the problem is having to go back to the database for every request.
That's exactly what the problem is. Unfortunately, the authentication scheme is a common sub-system for every web-app on this server. About 30 in total. This is a custom authentication scheme, so I'd have to completely re-write it & that's not an option. However, I may be able to tack on the file part & let the image.php file reference that. Hmmm....
Thanks for the idea.

Posted: Wed May 31, 2006 5:42 pm
by Christopher
pickle wrote:This is a custom authentication scheme, so I'd have to completely re-write it & that's not an option. However, I may be able to tack on the file part & let the image.php file reference that.
Buy a book on Refactoring and prove yourself wrong. You may suprise yourself. ;)

Posted: Wed May 31, 2006 6:30 pm
by pickle
Update:

I've done what ~arborint suggested (kind of ;)). When the person first enters the system, their session information is written to a file. Every time my image.php file is loaded, it checks that file for a valid session id. If it finds one, it shows the image. If it doesn't, it shows a blank image. The page load time for 27 images is 0.7 seconds - which will work just fine.

Thanks ~arborint!