...

View Full Version : Filtering



LearningCoder
08-11-2012, 08:01 PM
Just wondering what the best sanitizing filter would be to use when dealing with file uploads?

Reading my book it tells me to always filter the filenames.

I'm on the php manual and reading the sanitize filters but I am undecided on which one to use.

http://www.php.net/manual/en/filter.filters.sanitize.php

Can anyone give any advice?

Regards,

LC.

AndrewGSW
08-11-2012, 08:53 PM
I'm not sure that any of those filters are suitable (on their own) for file uploads.

I like this code:


//Check for valid upload
if($_FILES['image']['error'] != UPLOAD_ERR_OK) {
echo 'Upload file error';
return;
}

//Check for valid upload
if(!is_uploaded_file($_FILES['image']['tmp_name'])) {
echo 'Invalid request';
return;
}

//Sanitize the filename (See note below)
$remove_these = array(' ','`','"','\'','\\','/');
$newname = str_replace($remove_these, '', $_FILES['image']['name']);

//Make the filename unique
$newname = time().'-'.$newname;

//Save the uploaded the file to another location
$upload_path = "/home/mysite/public_html/uploads/$newname";
move_uploaded_file($_FILES['image']['tmp_name'], $upload_path);

found at phpsense (http://phpsense.com/2007/php-file-uploading/). It's a few years old though (2007) but it's a good page.

LearningCoder
08-11-2012, 11:09 PM
Thank you very much. I prefer the code you have to mine. Mine is relying heavily on if statements. Here is what I have so far:


<?php

//DEFINE FUNCTION TO DEAL WITH EXISTING FILE NAMES IN TARGET DIRECTORY. ADDS DIGITS TO END OF FILENAME. RETURNS AMMENDED FILENAME.
function editName($data){
$info = pathinfo($data);//retrieves info on the file path.
$data = basename($data,'.'.$info['extension']);//returns just the filename - without extension.
$data .= rand(10, 99);//concatenates a random 2 digit number onto the end of the file name.
$data = $data.'.'.$info['extension'];//concatenates the extension of the file back onto the new filename.
return $data;//returns the new filename.
}

//DEFINE ERROR ARRAY.
$all_errors = array();
$all_errors[0] = "<strong>Couldn't move file.</strong>";
$all_errors[1] = "<strong>Corrupt file name.</strong>";
$all_errors[2] = "<strong>There was an error uploading the file.</strong>";
$all_errors[3] = "<strong>No file found.</strong>";
$all_errors[4] = "<strong>Wrong file type. You can only upload .dem files (Gaming demo files).</strong>";
$all_errors[5] = "<strong>File size too large. You can only upload demos which are 10mb or less.</strong>";
$all_errors[6] = "<strong>There was an error with the server.</strong>";
$all_errors[7] = "<strong>Could not move the uploaded file.</strong>";

$MAX_FILE_SIZE = $_POST['MAX_FILE_SIZE'];//grabs the max_file_size value specified in the HTML form.
$file_dir = "files";//holds the target directory for the given file.
$error = $_FILES['fileupload']['error'];//holds error value.
$dot = substr_count($_FILES['fileupload']['name'],".");//counts how many fullstops within the filename.
$ext = pathinfo($_FILES['fileupload']['name']);//returns array of information regarding file.
$ext = $ext['extension'];//holds just extension of file.

if($_SERVER['REQUEST_METHOD'] == "POST"){

if($error == 0){

if(is_uploaded_file($_FILES['fileupload']['tmp_name'])){

foreach($_FILES as $file_name => $file_array){
echo $file_array['tmp_name']."<br />\n";
echo $file_array['name']."<br />\n";
echo $file_array['type']."<br />\n";
echo $file_array['size']."<br />\n";
}

if(file_exists($file_dir."/".$file_array['name'])){
$name = editName($file_array['name']);
echo "{$name}<br />";
}

if($dot == 1){

if($ext == "dem" and $file_array['type'] == "application/octet-stream"){
echo "<strong>type and extension ok...</strong><br />";

if($file_array['size'] <= $MAX_FILE_SIZE){
echo "<strong>file size ok...</strong><br />";

if(move_uploaded_file($file_array['tmp_name'], $file_dir."/".$name)){
//insert info to database...
echo "<strong>inserting data into database...</strong>";
$db_ok = TRUE;





}
else{
echo "{$all_errors[7]}";
}


}
else{
echo "{$all_errors[5]}";
}

}
else{
echo "{$all_errors[4]}";
}
}
else{
echo "{$all_errors[1]}";
}
}
else{
echo "{$all_errors[0]}";
}
}
else{
echo "{$all_errors[2]}";
}
}
else{
echo "{$all_errors[6]}";
}

if($db_ok){

require("connect.php");




}

?>


Would it be better to put most of that code in a series of if..else statements?

Kind regards,

LC.

DrDOS
08-11-2012, 11:19 PM
Don't depend upon filenames alone as a filter. Use something that can read the file header to check the actual filetype. Those are the best filters.

LearningCoder
08-12-2012, 11:27 AM
How would I go about doing the above? Header information is sent before any html/output, so would I have to read the file contents upon execution of the action script/form submission?

Kind regards,

LC.

DrDOS
08-12-2012, 05:07 PM
How would I go about doing the above? Header information is sent before any html/output, so would I have to read the file contents upon execution of the action script/form submission?

Kind regards,
LC.

You can't read it before the form submits but you can read it while it is a $_FILE['tmp_name'] so you don't have to save it or move it.

Dormilich
08-13-2012, 09:22 AM
PHP offers several functions/classes to get information about files:
- fileinfo (http://www.php.net/manual/en/book.fileinfo.php) functions
- filesystem (http://www.php.net/manual/en/book.filesystem.php) functions
- SPL File Handling (http://www.php.net/manual/en/spl.files.php)



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum