file upload in php - php

I am using php upload function to upload the files in my interface. I am using firefox-3.6.11 in my browser. I am uploading excel sheets. I have tried to get the uploaded file type.I have tested the file type with following way,
$Type = $HTTP_POST_FILES['TS_FILE']['type'];
$Data = split ("/", $Type,2 ) ;
if( "$Data[1]" != "vnd.ms-excel" && $Data[1]!="octet-stream" && "$Data[1]"!="xls" && "$Data[1]" != "excel" )
{
echo "<script> //alert ( 'inside alert' ) ;
alert ( 'The selected file is not in .xls format. Please select proper file.' ) ;
</script>";
exit;
}
It works fine. But some time I got the alert message as I mentioned in my code even if I upload the excel sheet. I don't know what is the exact problem. Is there any other excel file type is available in firefox versions???

The value of $_FILES['file']['type'] is sent by the browser, and the browser gets this value from the underlying OS. If I configure windows and tell it that .xls have mime type image/jpeg, my browser (be it firefox, IE or whatever) would send that type to your application.
So, basically, don't rely on $_FILES['file']['type'] to do the validation. Get this value yourself server-side using php's fileinfo:
$finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
$type = finfo_file($finfo, $_FILES['file']['tmpname']);
Also, you can get a list of used mimetypes for excel files from this site: http://filext.com/file-extension/XLS
edit: $_FILES instead of $_SERVER (sorry, it's early here)

I don't know where the error is in your code as I haven't uploaded files close to that way.
I've allways used the example on W3Schools http://w3schools.com/php/php_file_upload.asp
And then edited it heavily to make it process the right kind of files (wich is where you seem to be stuck).
The way you'd want to check the file type is using $_POST['file']['type']
I see that you are indeed using this but perhaps not correctly.
You can look on W3S how they do file type checking for images, this can also be used for xls.
The way to find out what your browser sends as file type is to simply trigger_error("File type is: ".$_POST['file']['type']);
Now you can make an if statement as they used on W3S to validate the file using the file type the trigger_error reported.
Please be aware that some browsers (especially IE) could use a different name.
(sorry for not being able to give you an answer to your own script but perhaps there are some things I said that might help)

Related

Using php to check MIME type of file uploaded via form

Ok, so I'm creating a website that will let users upload csv-files that are to be scanned in to a mySQL-databse. Because I don't want to risk evil people uploading strange files that can mess with my database I'm guessing it's a good idea to check the mime type of the file. From other threads I've understood that the only way to properly do this is by using finfo(). But I don't get it to work. The following code in my uploadfile.php just prints out the temporary file name followed by "hello".
$filename = $_FILES["file"]["temp_name"];
echo $filename;
if (function_exists('finfo_open')&&$mode==0) {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
echo finfo_file($finfo,$filename);
finfo_close($finfo);
echo "hello";
}
So I know that the file has uploaded correctly, I know the function exists, I know that there is no error throughout the if clause. So then why won't it work?
I'm testing this through MAMP, and am thinking that maybe there is some error there? Though it has PHP Version 5.4.4.
I have also tried different versions like:
$mimetype = finfo_file($finfo,$filename);
echo $mimetype;
But nothing works. It never prints any mime type :( What can I do to fix this?
finfo_file can and will return empty string and FALSE if the type is not found.
Problem with mime types here is, you can't trust them either.
I did this before and parsed the files with fgetcsv. Any error there and I discarded the file. This way you can be sure it was valid csv.
When you insert into your database make sure you do the proper escaping or use prepared statements.

Best Mime Type Method

Whats the best way to determine the mime type or file type , stopping anything malicious getting through and making sure a bug doesn't get in your system.
In my example I need a way of screening so just .mp3 are uploaded to the site. Now I know there is mime_content_type but that gives odd results depending on how the file was made and what browser you use, seeing as it gets its data from the browser, at least that's how I understand it.
this is my code for identifying using mime type.
if(mime_content_type_new($_FILES["userfile"]) == 'audio/mpeg' ) { do stuff }
then there is using unix command line and interpreting that
$fileinfo = exec("file -b 'song.mp3'"); echo $filinfo;
this outputs something like this.
Audio file with ID3 version 2.3.0, contains: MPEG ADTS, layer III, v1,
192 kbps, 44.1 kHz, Stereo
so we can sort through and check this t match to our file type.
$fileinfo = exec("file -b 'song.mp3'");
$filewewant = "MPEG";
$mpeg = stripos($fileinfo, $filewewant);
$filewewant = "layer III";
$mpeg3 = stripos($fileinfo, $filewewant);
if ($mpeg !== False & $mpeg3 !== False)
{ echo "success"; };
this way seems to work better, regardless of named extension (eg is it renamed it .png) but requires the file to be saved first then sorted through,and doesn't work on windows.
I've also been pointed at http://pear.php.net/package/MIME_Type
Does anyone else have a better way of doing it ? what is the correct way to identify what files are being uploaded to your server ?
MIME types are (should be) obtained by looking at the file's MIME header, a piece of data at the beginning of the file that indicates the MIME.
This is exactly what mime_content_type_new and your UNIX command are doing, so no issue there.
Not sure what you mean by a "better" way, you're doing it correctly.
If you are getting different MIME type results because of a browser issue, you should probably create an array of acceptable values and check it with the in_array() method.
I wouldn't recommend leaving MIME type checks like that in the hands of client-side code, especially when security is a big issue. The client has access to the code so it is much easier to fool.
You could, however, do a check on both the client side and the server side. This will save you bandwidth from bad uploads, but still keep the system secure from malicious users.
Here's a nice tutorial on Javascript's FILE API and processing images with Javascript.
http://www.html5rocks.com/en/tutorials/file/dndfiles/
Cheers.
This it maybe not a proof solution (just new / current browsers), but the new javascript FILE API allows to read the MIME-TYPE without uploading the file.
For any server-side validation you have to upload the file -> and you should validate them.

mp3 upload mimetype being missed by firefox specically

I have a file upload, it works great in everything except for firefox, it keeps saying the mimetype isnt supported. This is my code:
if(isset($_POST[submitfile]))
{
$uploadedsong = $_FILES['soup']['tmp_name'];
$mimetype = $_FILES['soup']['type'];
if($mimetype=="audio/mpeg"||$mimetype=="audio/x-mpeg-3"||$mimetype=="audio/mp3"||$mimetype=="audio/x-mpeg"||$mimetype=="audio/x-mp3"||$mimetype=="audio/mpeg3"||$mimetype=="audio/x-mpeg3"||$mimetype=="audio/mpg"||$mimetype=="audio/x-mpg"||$mimetype=="audio/x-mpegaudio")
{
This is allowing uploads for every browser, EXCEPT firefox! extremely frustrating, i dont know why this is happening. Any ideas?
The mime-type for the file-upload is totally informative and not further explicitly (and specifically) binding of what's-o-ever. Don't rely to it.
Firefox is doing nothing wrong here, it's the wrong expectations you've coded into your script - from the PHP Manual­Docs:
$_FILES['userfile']['type']
The mime type of the file, if the browser provided this information. An example would be "image/gif". This mime type is however not checked on the PHP side and therefore don't take its value for granted.
So the use of this information is limited, it is not strict.
You should log which mime-type was uploaded, because you can't test against all browser/OS combinations.
Inspecting the file is necessary as well if you want to ensure it follows the convention of a mp3 file. Next to fileinfo­Docs (which is for all files), there is php-reader and Zend_Mimme_Magic and a lot of other mp3 files related libraries.
Try using this to get the mime type
$file_info = new finfo(FILEINFO_MIME);
$mime_type = $file_info->file($file);

How to restrict file upload using PHP?

I am trying to do a restricted file upload using PHP.
I have used
if (($_FILES["file"]["type"] == "application/dbase")
||($_FILES["file"]["type"] == "application/dbf")
||($_FILES["file"]["type"] == "application/x-dbase")
||($_FILES["file"]["type"] == "application/x-dbf")
||($_FILES["file"]["type"] == "zz-application/zz-winassoc-dbf"))
For me .dbf (i.e Microsoft Visual FoxPro Table type) files are not working. Please suggest to me what I should put for the content type for .dbf .
The browser uploading the file probably doesn't know it's an application/dbf mime-time, and sends it as the generic "application/octet-stream". The client/browser has to set the mime-type to be known on upload, and this can be altered by the user!
Thus MIME-type isn't reliable. If you want to be sure that it's the correct file-type/format, you'll have to examine the uploaded file.
There is another easy way for this problem , instead of inspecting the MIME type,
we can get the file extension of the uploaded file by using this function.
$filename=$_FILES["file"]["tmp_name"];
$ext = pathinfo($filename, PATHINFO_EXTENSION);
$ext = strtolower($ext);
if($ext=="png"||$ext=="gif"||$ext=="jpg"||$ext=="jpeg"||$ext=="pdf"
||$ext=="doc"||$ext=="docx"||$ext=="xls"
||$ext=="xlsx"||$ext=="xlsm"||$ext=="dbf")
{
// your code whatever you want to write;
}
Find an easy blob-upload and download of file here Blob-upload
Defining the content type is up to the browser (or other client application), making it easy to tamper with and cannot be relied upon. My guess is that your browser doesn't recognize the .dbf file and defaults to "application/octet-stream".
You can't depend on the type field of a file upload to actually determine its type. First, it can be spoofed by the client. Secondly, the client simply might not know what the file type actually is and just report 'application/octet-stream' instead.
you'll have to determine what kind of file was uploaded yourself. Fortunately, PHP provides the fileinfo extension, which can help you with determining the type of a file.
Code example based on one from php.net:
<?php
$finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
echo finfo_file($finfo, $_FILES["file"]["tmp_name"]) . "\n";
finfo_close($finfo);
?>
http://www.php.net/manual/en/ref.fileinfo.php
Try inspecting the MIME type being passed to you when you upload a file of that type. Insert a temporary print $_FILES["file"]["type"]; somewhere in your code, then upload the file to run the code and see what it prints out! You can then copy that type and use it in your if-statement.

Limiting file upload type

Simple question. Is there a way to only allow txt files upon uploading? I've looked around and all I find is text/php, which allows PHP.
$uploaded_type=="text/php
When you upload a file with PHP its stored in the $_FILES array. Within this there is a key called "type" which has the mime type of the file EG $_FILES['file']['type']
So to check it is a txt file you do
if($_FILES['file']['type'] == 'text/plain'){
//Do stuff with it.
}
It's explained very well here. Also, don't rely on file extentions it's very unreliable.
Simply put: there's no way. Browsers don't consistently support type limiters on file upload fields (AFAIK that was planned or even is integrated into the HTML standard, but barely implemented at best). Both the file extension and mime-type information are user supplied and hence can't be trusted.
You can really only try to parse the file and see if it validates to whatever format you expect, that's the only reliable way. What you need to be careful with are buffer overflows and the like caused by maliciously malformed files. If all you want are text files, that's probably not such a big deal though.
You could check the mime type of the uploading file. In codeIgniter, this code is used in the upload library:
$this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$field]['type']);
The variable $this->file_type then used to check the upload configuration, to see if the uploaded file is in allowed type or not. You can see the complete code in the CodeIgniter upload library file.
You need to check the file extension of the uploaded file.
There is Pear HttpUpload, it supports this.

Categories