I have a php file called gallery.php which is the page for a user specific gallery of images. For security, the user images are stored outside of web root.
To retrieve the appropriate files for each user, I use a getimage.php file which serves the images from their location. All in all, the directory structure looks like this:
- UserImages
- User1
- List of user1's images
- User 2
- List of user2's images
- User1
- public_html
- gallery.php
- getimage.php
getimage.php is written as follows:
$imgString = realpath('/UserImages/' . $_SESSION['username'] . '/' . $_GET['img']);
if (!startsWith($imgString, '/UserImages/' . $_SESSION['username'] . '/')
|| !(endsWith(strtolower($imgString), '.jpg') || endsWith(strtolower($imgString), '.jpeg')))
{
header('HTTP/1.0 403 Forbidden');
die();
}
$img = file_get_contents($imgString);
header("Content-type: image/jpeg");
echo($img);
exit();
I rely on $_GET['img'] to determine which image to retrieve, which is a possible security hole (and a major one at that). I could forsee a directory traversal attack, hence the use of realpath, though I'm sure there can be other avenues of attack I do not contain with this script.
For that reason, I'd prefer if I could move getimage.php outside of webroot, or at least prevent it from being accessible directly (and only through gallery.php, where the sent img parameter is strictly under my control).
Any time I try to move getimage.php oustide of public_html however, I can't seem to call it anymore even if I do a require or include in gallery.php. The way I access getimage.php is doing this:
<img src=getimage.php?img=IMG_FILENAME.jpg />
But getimage.php will fail if I ever move it out of the public_html directory.
So, long story short: what do I need to do to prevent getimage.php from being abused?