Securing this script [solved]

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
jabbaonthedais
Forum Contributor
Posts: 127
Joined: Wed Aug 18, 2004 12:08 pm

Securing this script [solved]

Post by jabbaonthedais »

This script is meant for my visitors to be able to upload images (gif/jpeg/png/whatever) to my server. My visitors are cookied before they get to this script, and if they have the cookie it asigns them a folder to upload to. This script works perfectly, just how I want it... except its not specific to images. Users can upload any file they want, even harmfull files. What is the most secure way to limit the types of files that can be uploaded? If anyone has time to help me out I would appreciate it! If its a pain I might could paypal you something for your trouble.. just let me know!

Again, this script works fine! I just don't think letting people upload any filetype is very secure!

Thanks for your time!! Here's my code:

Code: Select all

<?php
require_once('control.php');  // just for cookie creation
          if ( isset($_COOKIE['affiliate']) ) 
          {

$mysql_access = mysql_connect("localhost","user","pass");
$db = 'database'; // mySQL database name
mysql_select_db("$db");

$query = "SELECT id FROM thumbs WHERE aff='".$_COOKIE['affiliate']."' ";
$result = mysql_query($query, $mysql_access);
if(mysql_num_rows($result)) { 
    // it is true

   while($row = mysql_fetch_row($result))
  {
  // get my number
    echo "<center><font face='Arial' size='2'><a target='_blank' href='/files/" . $row[0] . "'>Click here to access your uploaded files (opens in new window)</a></center><p>";
$pathz = $row[0];
  }

} else {
   // false, so it doesn't exist
}

if($nid) {

if($pathz) {

} else {
   // false, so it doesn't exist

$tablename 		= "thumbs";
$next_increment 	= 0;
$qShowStatus 		= "SHOW TABLE STATUS LIKE '$tablename'";
$qShowStatusResult 	= mysql_query($qShowStatus) or die ( "Query failed: " . mysql_error() . "<br/>" . $qShowStatus );

$row = mysql_fetch_assoc($qShowStatusResult);
$next_increment = $row['Auto_increment'];


$aidd = $_COOKIE['affiliate'];
$sql4 = "INSERT INTO `thumbs` (`id`, `aff`) VALUES (" . $next_increment . ", " . $aidd . ")";
mysql_query($sql4, $mysql_access) or die ( "Query failed: " . mysql_error() );

$pathz = $next_increment;

}

$save_path = "/home/southern/public_html/files/" . $pathz . "/";    
$file = $_FILES['userfile'];
$k = count($file['name']);
?>
<center>
  <table border="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="500">
    <tr>
      <td width="100%"><br><font face='Arial' size='2'><center>Files successfully uploaded!</center><p><b>Uploaded File URL's</b>:<br>

<?
for($i=0 ; $i < $k ; $i++)
{
	if($i %2)
	{
		echo '';
	}
	else
	{	
		echo '';
	}
	

	echo "<a target='_blank' href='http://www.mysite.com/files/" . $pathz . "/"  . $file['name'][$i] . "'>http://www.mysite.com/files/" . $pathz  . "/"  . $file['name'][$i] . "</a><br>";

	if(isset($save_path) && $save_path!="")
	{
		$name = split('/',$file['name'][$i]);

		move_uploaded_file($file['tmp_name'][$i], $save_path . $name[count($name)-1]);
	}
}

echo "</td></tr></table><p>";
?>
<form  enctype="multipart/form-data" action="upload.php" method="post">	

<table border="0" cellpadding="10" align="center" width="639" align="center">
<tr><td width="615">
<p align="center"><b><font face="Verdana" color="#FF0000">Upload Images</font></b></td>
</tr>
<tr>
  <td  valign="top" align="center" width="615">
	<table border=0 align="center" cellpadding=3>
	<tr><td><input type="file" name="userfile[0]" size="20"></td></tr>
	<tr><td><input type="file" name="userfile[1]" size="20"></td></tr>
	<tr><td><input type="file" name="userfile[2]" size="20"></td></tr>
	<tr><td colspan=2 align="center">
		<input type="hidden" name="nid" value="1">
		<input type="hidden" name="sessionid" value="<?= $sid ?>">
		<input type="submit" value="Upload Files">
	</td></tr></table>
</td>
</tr>
<tr><td width="615">
<p align="center"><font face="Arial" size="2">Select one or more image files from your 
computer and click Upload Files.</font></table>
</form>
<?
} else {
?>

<form  enctype="multipart/form-data" action="upload.php" method="post">	

<table border="0" cellpadding="10" align="center" width="639" align="center">
<tr><td width="615">
<p align="center"><b><font face="Verdana" color="#FF0000">Upload Images</font></b></td>
</tr>
<tr>
  <td  valign="top" align="center" width="615">
	<table border=0 align="center" cellpadding=3>
	<tr><td><input type="file" name="userfile[0]" size="20"></td></tr>
	<tr><td><input type="file" name="userfile[1]" size="20"></td></tr>
	<tr><td><input type="file" name="userfile[2]" size="20"></td></tr>
	<tr><td colspan=2 align="center">
		<input type="hidden" name="nid" value="1">
		<input type="hidden" name="sessionid" value="<?= $sid ?>">
		<input type="submit" value="Upload Files">
	</td></tr></table>
</td>
</tr>
<tr><td width="615">
<p align="center"><font face="Arial" size="2">Select one or more files from your 
computer and click Upload Files.</font></table>
</form>
<?
}
          }
          else 
          {
          	echo "Log in to upload files!";
          }
?>
Last edited by jabbaonthedais on Thu Mar 30, 2006 1:55 am, edited 1 time in total.
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

run getimagesize() on the image
this should return an array of information about the picture

Code: Select all

$picinfo = getimagesize($picture);
the index 2 is what's important

you could make an array of allowed file types and check if its in the array

Code: Select all

$allowed_types = array('jpg','jpeg','png'); // etc
if(!in_array($picinfo[2],$allowed_types)){
   die('invalid file type');
}
of course you'll have to change the array to the values getimagesize would return. (i forget off the top of my head)
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
jabbaonthedais
Forum Contributor
Posts: 127
Joined: Wed Aug 18, 2004 12:08 pm

Post by jabbaonthedais »

Ok, I haven't slept in forever so forgive me if this is a stupid question. How do I get getimagesize() to check the file before it puts it into the path (to prevent bad files from uploading)? When I put the code in my script, it can't find the file to check... See below:

Code: Select all

if(isset($save_path) && $save_path!="")
	{
// check file to see if its an image
list($width, $height, $type, $attr) = getimagesize($file['name']);
if ($type == 1 or $type == 2 or $type == 3) {
// good file type, so move it

		$name = split('/',$file['name'][$i]);
		
		move_uploaded_file($file['tmp_name'][$i], $save_path . $name[count($name)-1]);
} else {
// bad file
echo "<p><font face='Verdana'>Bad filetype. Try again!<p>";
}
	}

}
When I use this, I get this error:
Warning: getimagesize(Array) [function.getimagesize]: failed to open stream: No such file or directory in /home/southern/public_html/upload.php on line 97
Thank you very much! Great function I never knew existed! And looks really easy to implement if I can get over the little things. :)
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

if it's from a direct upload via a form

you can run it on $_FILES['name']['tmp_name']

ie

Code: Select all

$picture_info = getimagesize($_FILES['field_name']['tmp_name']);
//    change "field_name" to the name of your file upload form element

$allowed = array('gif','jpg','png');
if(!in_array($picture_info[2],$allowed)){
   echo 'not allowed';
}
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
jabbaonthedais
Forum Contributor
Posts: 127
Joined: Wed Aug 18, 2004 12:08 pm

Post by jabbaonthedais »

scottayy wrote:if it's from a direct upload via a form

you can run it on $_FILES['name']['tmp_name']

ie

Code: Select all

$picture_info = getimagesize($_FILES['field_name']['tmp_name']);
//    change "field_name" to the name of your file upload form element

$allowed = array('gif','jpg','png');
if(!in_array($picture_info[2],$allowed)){
   echo 'not allowed';
}
Thanks! That got it working :)

The only thing is the way it is now, if the user only uploads 1 file, the other two (blank fields) show as bad files.

For example, if you upload one file, this is the result:
Uploaded File URL's:
http://www.mysite.com/files/1/testfile.gif
http://www.mysite.com/files/1/


Bad filetype. Try again!

http://www.mysite.com/files/1/


Bad filetype. Try again!

I tried several IF statements to determine if $file['name'][$i] is set, it would display the url, but if not, it would do nothing. But it always shows the url. Somehow it either thinks that variable is set reguardless, or there is something with the way I'm writing it that I'm not doing right.
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

getimagesize only checks for images

so .txt would fail

if you're doing it in a loop, you could do

Code: Select all

foreach($_FILES['field_name']['name'] AS $v){
   if(!empty($v)){
      //    do your stuff here
   }
}
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
jabbaonthedais
Forum Contributor
Posts: 127
Joined: Wed Aug 18, 2004 12:08 pm

Post by jabbaonthedais »

Thanks scottayy! You are my hero! :D

Everything is working great. Really appreciate it! Now maybe I can sleep ;)
Post Reply