Log in

View Full Version : [php] Best way of uploading files?



Joe!
17-11-2008, 09:29 PM
So i'm making an image gallery script for my college project. I've coded the thing from scratch and i'm wanting to know what would be the best way to approach the actual uploading process.
I need to have categorys(albums). All of the image uploading will be done via the backend part of the script. So far in my MySQL database I have an images tables which i'm going to use to store all the information on an image, this includes an album ID. There is an albums table which just stores album info, such as the name, date and the unique ID. Obviously the album ID's are what im going to use to display an album on a page. So i'll make it search for all images with the album ID '1' for example and it will display them. This is the best way I can think of to approach that part, i'm open to suggestions though.
I just want to know the safest way of uploading the files, i've secured the script so no one but an admin can get to the uploading page, but I want to make sure an admin can't upload a dodgey file, so far i've got this;

if (isset($_POST['album']))
{
if ((($_FILES["file"]["type"] == "image/gif") || ($_FILES["file"]["type"] ==
"image/png") || ($_FILES["file"]["type"] == "image/jpeg") || ($_FILES["file"]["type"] ==
"image/pjpeg")) && ($_FILES["file"]["size"] < 200000))
{
if ($_FILES["file"]["error"] > 0)
{
echo "Error: " . $_FILES["file"]["error"] . "<br />";
}
else
{


if (file_exists("uploads/" . $_FILES["file"]["name"]))
{
echo $_FILES["file"]["name"] . " already exists. ";
}
else
{
move_uploaded_file($_FILES["file"]["tmp_name"], "uploads/" . $_FILES["file"]["name"]);
$imgurl = "/uploads/" . $_FILES["file"]["name"] . "";
$insertimg = "INSERT INTO `images` (`id`, `file`, `caption`, `album`) VALUES (NULL, '".$imgurl."', 'a caption', '1')";
$insertimgqry = mysql_query($insertimg);
if (!$insertimgqry)
{
die(mysql_error());
}
echo "Done.";
}
}
}
else
{
echo "Invalid file";
}
}
else
{
echo "<form method='post' id='imageupload' enctype='multipart/form-data'>
<input type='file' name='file' id='file' />
<input type='text' name='album' id='album' />
<input name='' type='submit' />
</form>";
}
Will this suffice? Or is there a better way?
+rep for helpful answers :)
Thanks

Dentafrice
20-11-2008, 01:50 AM
Well all you are really doing is checking the mime submitted through the POST data..

Anyone could easily change the header (Content-Type) to image/png and still have the extension .php and it will be uploaded ;)

Joe!
20-11-2008, 10:26 AM
How would I go about preventing that then? :) Thanks

Iszak
20-11-2008, 02:43 PM
You'd use the finfo extension seen here http://www.php.net/manual/en/ref.fileinfo.php to get the mime type of the files, and check if it corresponds with the provided type of the uploaded file ($_FILES[]['type']). As I believe $_FILES[]['type'] works by using the file extension and associated it with that type, e.g. if you renamed a .gif to .jpg it'll be seen as image/jpeg despite being a .gif, this is why you need to check the mime type.

Dentafrice
20-11-2008, 09:45 PM
You'd use the finfo extension seen here http://www.php.net/manual/en/ref.fileinfo.php to get the mime type of the files, and check if it corresponds with the provided type of the uploaded file ($_FILES[]['type']). As I believe $_FILES[]['type'] works by using the file extension and associated it with that type, e.g. if you renamed a .gif to .jpg it'll be seen as image/jpeg despite being a .gif, this is why you need to check the mime type.
Headers are not based on extensions.. so the extension doesn't determine the file type.
-----

Here's my old process of uploading files:

1. replace special characters in filename (" ", %, (, ), ', ", \\, /)
2. use getimagesize() [don't have to use finfo] returns an array (ex: $blah = getimagesize($file); $mime = $blah["mime"])

3. Check the extension from a blacklist.. here's how I did it:



$blacklist = array (".shtml", ".phtml", ".htaccess", ".htpasswd", ".cgi", ".pl", ".asp", ".aspx", ".cfm", ".html", ".php", ".phtml", ".php3", ".php4", ".phps", ".php.inc" );
foreach( $blacklist as $item ) {
if(preg_match( "/$item\$/i", $_FILES ['images'] ['name'] [$key] )) {
$this->core->error( "We do not allow uploading of those files." );
}
}


Check mime type (provided by getimagesize which checks the headers) against a pattern:

"image/*"


and you should be fine..

Want to hide these adverts? Register an account for free!