I´m looking for a secure way to mix html and binary data. The binary data is a streamed image.
The idea is to create a secure way to protect images from direct view (i.e http://www/image.jpg).
The image should only be displayed to authorized users.
So far, I have found several methods to display the image using fpassthru() and fopen() (among others).
The script works great, as long as the only thing output to the browser is the image itself. As soon as I add a line of html, all I see is binary data instead of an image.
This works:
$file = "/path/to/image/image.jpg";
$fhandle = fopen($file, "rb");
$fdata = fread($fhandle, filesize($file));
fclose($fhandle);
Header("Content-type: image/jpeg");
echo $fdata;
This doesn't
echo "an image";
$file = "/path/to/image/image.jpg";
$fhandle = fopen($file, "rb");
$fdata = fread($fhandle, filesize($file));
fclose($fhandle);
Header("Content-type: image/jpeg");
echo $fdata;
I think it has something to do with the headers. The server first sends a header telling the browser there is a textfile coming up and all of the sudden binary data appears. I did find this workaround:
<img src='image.php?image=imagefilename'>
This way I can mix html and binary data, if image.php contains something like this:
if(!empty($_GET['image']))
{
$name = "/path/to/image/".$_GET['image'];
$fp = fopen($name, 'rb');
header("Content-Type: image/jpg");
header("Content-Length: " . filesize($name));
fpassthru($fp);
}
However, the above method leaves one weakness: a user can access the image directly, like so:
http://www/image.php?image=imagefilename.
Thereby rendering the user authentication system useless at best, at worst any file on the system can be viewed, so proper input validation is a must!
The only way I can solve this is to append the user uthentication layer to image.php. That is however, not desired. Let's say, for the sake of the argument, that multiple images will be viewed. Not very efficient to verify that the user is logged on and has access to the specific file every time image.php is called. Especially, if the access information is stored in a db.
Is there another way to mix binary and html data? This would enable me to write a file that authenticate the user only once.
So far, I´ve been running around in circles and can't find, what seems to be, a simple answer. Any thoughts?