SitePoint Sponsor

User Tag List

Results 1 to 5 of 5
  1. #1
    SitePoint Member
    Join Date
    Mar 2012
    Posts
    4
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Uploading images with imagecreatefromjpeg() security question

    Apologies if this is answered elsewhere. I was not able to find a similar post.

    I need some expert advice on security issues with uploaded images in a PHP application.

    Briefly, I have a web app that displays uploaded images as a slideshow. The images are uploaded by the user through a custom-built CMS (which is on the same domain as the public pages) and records are sent to a database that include the filename as it was on the user's computer. Everything is working okay, however I decided to put the upload directory for the images outside or above the webroot, so e.g.

    domain name points to public_html,
    host/public_html/index.html is home page,
    host/uploads/ is where the upload folder is

    The images are now accessed in something like the following manner from the slidehsow page:
    <?php
    $query = "SELECT filename,imgID FROM pics";
    $result = mysqli_query($dbconnect,$query);
    while($record = mysqli_fetch_array($result)) {
    echo '<div class="slide"><img src="fetch_image.php?file=' . $record['filename'] .'" id="slide_' . $record['imgID'] . '" /></div>';
    }
    ?>

    fetch_image.php looks something like:
    <?php # fetch_image.php

    if(isset($_GET['file'])) {

    // Access the root directory
    $root_dir = dirname(dirname(dirname(__FILE__)));

    $file = $root_dir. '/uploads/' . $_GET['file'];
    $size = getimagesize($file);

    if (file_exists($file) && $size) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    ob_clean();
    flush();
    readfile($file);
    exit;
    }
    }

    The divs with class 'slide' in the generated HTML have absolute positioning and display:none so all will stack up on top of each other and are hidden when the page loads. A javascript file controls the slideshow by showing and hiding instances of 'slide' according to thumbnail links clicked by the user.

    This works a treat, however, and I'm coming to the point, considering that in the Content Management System the file upload script creates a copy of the uploaded file using imagecreatefromjpeg() and imagecopyresampled(), is this layer of security unecessary? In other words would it be safe to use relative links (e.g. /images/thefile.jpg) here and move the upload directory inside the webroot? There doesn't seem to be a lag in performance as it is, but if there were 20 images that would be 40 page requests (there is a row of thumbnail images), does that make a significant difference to demands on resources and speed? I don't know if having upload dir above webroot makes any difference at all in this situation.

    BTW the upload script is part of a freely available file upload kit and I'm not sure if it's permitted to place any lifted code from it here. It's the jquery fileuploader.

    I have been googling this subject for the past two days and am really surprised that such a common application of PHP is not better documented.

    Any ideas on the subject would be most welcome.

  2. #2
    SitePoint Member
    Join Date
    Mar 2012
    Posts
    4
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by danielz View Post
    why dont you use external links for upload
    Could you elabourate a bit. Do you mean absolute paths?

  3. #3
    SitePoint Wizard lorenw's Avatar
    Join Date
    Feb 2005
    Location
    was rainy Oregon now sunny Florida
    Posts
    1,104
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    This part is the weakness,
    PHP Code:
    $file $root_dir'/uploads/' $_GET['file']; 
    Make sure you have an array of the files you have in uploads and check to see if it is in the array, $_GET['file'] could have the path ../evilfile.php or even a path to a domain.
    If you allow the public to upload files, make sure they can't upload files with .php .js and .htaccess codes. htmlPurifier can be your friend.
    What I lack in acuracy I make up for in misteaks

  4. #4
    SitePoint Member
    Join Date
    Mar 2012
    Posts
    4
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for pointing that out lorenw.

    I would also use mysql_real_escape_string() before making a query too.

    I think what I need is a pointer to a good book or online resource which will explain a bit more in depth about securing web apps such as this. I'm aware of the basic principles but feel like I'm getting lost in a mesh of security measures and circumventing code, and could probably do things in a much simpler way.

  5. #5
    SitePoint Member
    Join Date
    Mar 2012
    Posts
    4
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'll try to make it clearer what I'm asking.

    If you look at the while loop in the code above you see that fetch_image.php is called as many times as there are images (twice in fact if you count the thumbnails). Does this amount to significant increase in overhead (over <img src="standard_path_to_file.eg." />). This is the kind of info I'm after. What's the best way to do this and maintain security? If anyone can point me in the right direction.

    Thanks


Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •