views:

843

answers:

3

I've inherited an application with a glaring security hole.

It has session-based security, but file uploads (which are user specific) are not secured in any way and they are stored in the public file tree.

Filenames do not follow any convention as such, making them hard to guess, but the data is sensitive and thus I need to implement a security measure to prevent unauthorized file access.

Moving the location of the files is not really an option, so I'm looking at a htaccess solution to forward requests to a php handler script.

Does anyone have experience in implementing this type of thing or any good alternative solutions? Specific examples of .htaccess syntax greatly appreciated, as I'm struggling in this area.

A: 

I think you may need to write a script that will serve the images, then use htaccess to completely restrict access to the actual images from a browser.

The script can take in the web path to the image, decide if the user has access, then use something like fpassthru to feed an actual image to the browser.

All references to the images would need to be modified, however, to reference the serving script.

So instead of accessing the images with /images/123/5423453245.jpg, it would be /image.php?images/123/5423453245.jpg

Or something similar to that.

Matt
I see what you're saying, but that's really what I need to avoid doing (changing the links). They're not images by the way :-)
BrynJ
+3  A: 

Don't really understand why moving them isn't an option, since pushing requests for them to a handler means it no longer matters where they're stored. But you're the man on the scene.

.htaccess looks like:

RewriteEngine on
RewriteRule path/to/where/these/files/live/(.*) /handlerscript.php/$1

Then you pick up the remaining file path and name from $_SERVER['PATH_INFO'].

chaos
Forgot about mod_rewrite.. this is a better solution.
Matt
Thanks, I will take a look at this solution - the reason for not wanting to move the location of the files is that users receive emails with links to their files (again, not me I hasten to add!). I guess it could still be done, but would require a little more work to handle the redirect?
BrynJ
Should have added to the above that I'll bounce the user to a login prompt in future (via the handler) if they're not logged in.
BrynJ
What I mean is that the URL you're publishing to your users no longer has any actual relationship to where the files live. You could move the whole hierarchy out to /var/app/foo/bar/baz and your handlerscript.php could push out the content from there just as well.
chaos
Very good point, I'll look to see how much work there is involved in updating file upload routines etc with the new path (not the tidiest of code bases!).
BrynJ
A: 

Well, you could make apache parse .jpg file's for a certain folder adding the following to your .htaccess

AddHandler php5-cgi .jpg

then you could set a file of php to parse the request the way chaos was recomending you and doing a certain validation, then just return jpeg headers along with the correct picture u'd like to display

here's an example

<?php
if($validUser)
    {
    header("Cache-control: No-cache");
    header("Pragma: No-cache");
    header("Content-Type: image/jpeg");
    //correct picture address
    $img = imagecreatefromjpeg("2326_b_lil.jpg");
    imagejpeg($img);
    }
    else
    {
    //code for error image
    }
?>

please let me know if you want a more extensive example

PERR0_HUNTER
The files are not generally images, but they might be. Your example got me thinking though - wouldn't it be better to just use readfile rather than recreating the image (your code converts to an uncompressed true colour file, then back to a jpeg)?
BrynJ
Im just using that function to easily load the file data and send it to the browser, you can replace this procedure with a simple fopen and echoing the input, since you already sent jpeg headers the browser will interp it as a image
PERR0_HUNTER