Welcome Guest, Not a member yet? Register   Sign In
Keep the peepers at bay!
#1

[eluser]dmstudios[/eluser]
In my app, users can upload photos and view their own photos.. currently, everyones photos are saved to an 'uploads' folder, and I store information about the users & their photos in mysql.

I can control who gets to view what photos just fine in CI, however..

How do I keep people from pulling up other users photos directly via URL?


Example scenario:

A user logs into his account, and looks at his photo at : http://domain.com/upload/path/123.jpg

and says, hmm.. I wonder what I could see if I change 123.jpg to maybe 456.jpg???

It would then pull up the 456.jpg no problem.. (as long as it exists, of course..)

How can I prevent that?
#2

[eluser]benurv[/eluser]
you should link to a controller, pointing to the database id of the file (not the file directly), the controller could fetch it an push it to the browser without the user knowing where the file came from or were it's stored.

This way your controller could check if the user has the right to view or not. i do it this way for secured images, i also store my images in a dir not accessible by public. It's a directory above the public html so completely hidden from the internet.
#3

[eluser]dmstudios[/eluser]
Yes! That works amazingly, thanks for the advice. For anyone else stuck on a similar issue, here's the controller method that I wrote..

Code:
class Photo extends Controller {
    
    public function view($filename)
    {
        // The path where the images are stored.
        $path = '../directory/above/webroot/';
              
        // Construct the actual image path.
        $imgPath = $path . $filename;
        
        // Make sure the file exists
        if(!file_exists($imgPath) || !is_file($imgPath)) {
            header('HTTP/1.0 404 Not Found');
            die('The file does not exist');
        }
        
        // Make sure the file is an image
        $imgData = getimagesize($imgPath);
        if(!$imgData) {
            header('HTTP/1.0 403 Forbidden');
            die('The file you requested is not an image.');
        }
        
        // Set the appropriate content-type
        // and provide the content-length.
        header('Content-type: ' . $imgData['mime']);
        header('Content-length: ' . filesize($imgPath));
        
        // Output the image to the browser
        readfile($imgPath);        
    }

}

Then you can simply link to :

Code:
<img src='/photo/view/image.jpg'>

That should be enough to get you started.. but as benurv suggested, you should send the ID of the filename, and not the filename itself. You should also be sure to change the name of the files that your users upload to something arbitrary.. that way a potentially malicious user won't know the name or location of the files they upload...

Thanks again benurv!
#4

[eluser]benurv[/eluser]
you'r welcome

i also store the original file name in my img table so when i push it back to the browser i use the original name.
To store the file i encrypt the filename using CI's file uploader class: http://ellislab.com/codeigniter/user-gui...ading.html

Hope it helps




Theme © iAndrew 2016 - Forum software by © MyBB