The following warnings occurred:
Warning [2] Undefined variable $unreadreports - Line: 26 - File: global.php(961) : eval()'d code PHP 8.1.2-1ubuntu2.14 (Linux)
File Line Function
/global.php(961) : eval()'d code 26 errorHandler->error
/global.php 961 eval
/printthread.php 16 require_once



UserSpice
Secure or manage access to images - Printable Version

+- UserSpice (https://userspice.com/forums)
+-- Forum: Support Center (https://userspice.com/forums/forumdisplay.php?fid=23)
+--- Forum: UserSpice 4.3 and Below (https://userspice.com/forums/forumdisplay.php?fid=26)
+--- Thread: Secure or manage access to images (/showthread.php?tid=1073)



Secure or manage access to images - jc - 06-04-2018

The standard code snippet
Code:
if(!hasPerm([3],$user->data()->id)){...}
can secure php pages but let open access to images, pdf files, text, etc. in the web server.

I have been looking at ways to secure those files to logged users and this is what I got, it may be useful for others and can be improved by the forum.

Let's assume all images are in folder "figures"

On the parent folder create a .htaccess file with these instructions (make sure mod_rewrite is enabled):

<pre>
Code:
RewriteEngine on
RewriteRule ^(figures)/(.*)$ imageout.php?img=$1/$2
</pre>

RewriteEngine on
RewriteRule ^(figures)/(.*)$ imageout.php?img=$1/$2

In this way when a file from the folder "figures" is requested the folder and filename are passed to the script imageout.php.

This script checks whether the user is logged in and send the image. It also prevents user input for files outside the designated folder. Imagine a user requests https://mydomain.com/figures/../../../../home/emabarrasingpictures/OMG.jpeg, not a good idea to let that happens (or put the images there in the first place).

This can be prevented by a code like:

<pre>
Code:
$fileOut =  basename($img);
//Prevent user input for files outside the designated folder
$fileOut = getcwd().'/figures/'.$fileOut;
</pre>


The file imageout.php serving the graphic files would be:

<pre>
Code:
<?php
// check whether user has permissions
require_once '../users/init.php';
if(!hasPerm([x],$user->data()->id)){
   header('Location: http://www.domain.com/');
   die();
}

if(!empty( $_GET['img'])){
$img = $_GET['img'];
} else { exit('Image not supplied');}

$fileOut =  basename($img);
//Prevent user input for files outside the designated folder
$fileOut = getcwd().'/figures/'.$fileOut;

if (file_exists($fileOut)) {
// from https://stackoverflow.com/questions/900207/return-a-php-page-as-an-image#26811487
    //Set the content-type header as appropriate
    $imageInfo = getimagesize($fileOut);
    switch ($imageInfo[2]) {
        case IMAGETYPE_JPEG:
            header("Content-Type: image/jpeg");
            break;
        case IMAGETYPE_GIF:
            header("Content-Type: image/gif");
            break;
        case IMAGETYPE_PNG:
            header("Content-Type: image/png");
            break;
       default:
            break;
    }

    // Set the content-length header
    header('Content-Length: ' . filesize($fileOut));

    // Write the image bytes to the client
    readfile($fileOut);
}
?>
</pre>

<?php
// check whether user has permissions
require_once '../users/init.php';
if(!hasPerm([x],$user->data()->id)){
header('Location: http://www.domain.com/');
die();
}

if(!empty( $_GET['img'])){
$img = $_GET['img'];
} else { exit('Image not supplied');}

$fileOut = basename($img);
//Prevent user input for files outside the designated folder
$fileOut = getcwd().'/figures/'.$fileOut;

if (file_exists($fileOut)) {
// from https://stackoverflow.com/questions/900207/return-a-php-page-as-an-image#26811487
//Set the content-type header as appropriate
$imageInfo = getimagesize($fileOut);
switch ($imageInfo[2]) {
case IMAGETYPE_JPEG:
header("Content-Type: image/jpeg");
break;
case IMAGETYPE_GIF:
header("Content-Type: image/gif");
break;
case IMAGETYPE_PNG:
header("Content-Type: image/png");
break;
default:
break;
}

// Set the content-length header
header('Content-Length: ' . filesize($fileOut));

// Write the image bytes to the client
readfile($fileOut);
}
?>
There is no noticeable decrease in speed for a few hundred files.