I am currently building a PHP application that lets users upload files. I am currently at the upload page, but my verification system does not work. I am using this system to validate files as audio files.
// Set our file name and extension
$fname = $_FILES['file']['name'];
$extension = strtolower(substr($fname, strpos($fname, '.') + 1));
// Check file
if ($extension == 'mp3' && $_FILES['file']['type'] == 'audio/mpeg') {
//File is valid mp3
} else {
//File is invalid
}
Now this doesn't work, but the weird thing is when I echo out $_FILES['file']['type'] it does not echo out a mime type for audio files. When I do this for any other file type, it echoes it out successfully.
It doesn't give a mime type only for audio files. I have tried it with WAV and M4A files, and it doesn't return one with any of these either. Is it something with the file type, or do I have to edit the .htaccess file or the MIME.types file in my xampp server. Also could there be a better way to validate uploaded files?
Also note that it does this on my xampp server, and the free server that I am using for test purposes.
Thanks for the help.
$_FILES['file']['type'] comes from the browser that uploads the file so you can't rely on this value at all.
Check out finfo_file for identifying file types based on file content. The extension of the file is also unreliable as the user could upload malicious code with an mp3 extension.
Related
I have a HTML form for entering a file and the php validates if the file entered is a xls file through the extension .xls !!
Now If a user renames a image or script file say abc.jpeg to abc.xsl the file wont be validated by the php code ! How can i validate if its truly a xls file irrespective of the extension?
Php code for validation
if(in_array($file_ext,$expensions)=== false)
{
echo "extension not allowed, please choose a .xls file.";
exit();
}
Instead of using file extension, I would suggest you to use mime_content_type that Returns the MIME content type for a file. Check link http://php.net/manual/en/function.mime-content-type.php for more info.
You can prepare an array having all the allowed MIME type/ file type then check MIME content type of your uploaded file using function mime_content_type.
echo mime_content_type('test.php'); // returns text/plain
This will help your code to validate file extension/file type in cross platform (Other OS compatibility) issue.
I am using move_file_upload on my server side in php so that client can allow users to upload their kml files to the server. I know that in order to check an image , in php I can use $check = getimagesize(file) but what would be the equivalent for a kml file check ?
I donot want to just check the extension of the file. I wish to know if infact the file is a valid kml file or not. If I only check the extension, someone can just post some other malicious file and change its extension to .kml
If you want to see if the file has the extension KML, you can use:
$filename = $_FILES["file"]["name"]; //or however you are getting the filename
$ext = end((explode(".",$filename)));
if($ext!="kml"){
//Extension is incorrect
}
Checking mime content can be helpful.
I am not quite sure what is the correct mime name of kml files but at least with checking in google it should be something as:
mime_content_type ($file) === 'application/vnd.google-earth.kml+xml'
How ever its possible that there are mimes set to 'application/xml' or 'text/xml' so extension validation is required as well ..
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.
I need to make a website that will allow registered users to upload audio files.
I wonder is there any bullet proof practice regarding security.
The site is built in PHP
Check mime type of uploading file
mp3 -> audio/mpeg
More here: http://www.w3schools.com/media/media_mimeref.asp
You will want to check the file type carefully. This means not just doing a substring on the file name to get the extension. The extension is not a concrete indicator of what the file actually is.
As Danzan said, you will want to check the MIME type of the file, using some code like this:
if ($_FILES["audioUpload"]["type"] == "audio/mpeg") {
//proceed with upload procedure
} else {
echo "Only mp3's are allowed to be uploaded.";
}
This reduces the chances of a user uploading, say, malicious PHP code into your upload directory to basically zero.
Bullet-proof file type check is provided via combination of getimagesize, fileinfo extension and mime_content_type function (Nette Framework property):
// $file is absolute path to the uploaded file
$info = #getimagesize($file); // # - files smaller than 12 bytes causes read error
if (isset($info['mime'])) {
return $info['mime'];
} elseif (extension_loaded('fileinfo')) {
$type = preg_replace('#[\s;].*$#', '', finfo_file(finfo_open(FILEINFO_MIME), $file));
} elseif (function_exists('mime_content_type')) {
$type = mime_content_type($file);
}
return isset($type) && preg_match('#^\S+/\S+$#', $type)
? $type
: 'application/octet-stream';
You can not trust any data coming from the client, because they can be easily forged.
You can upload anything with PHP. Here's an example: http://www.tizag.com/phpT/fileupload.php
Regarding security, you have to verify that only certain people are allowed to upload stuff and that you verify the contents of what they're uploading (file size, file type, etc).
From what I understand, images (jpeg, gif, etc.) might contain valid PHP/Python/Perl etc. code. So - anyone can create file that will be valid jpeg at the same time can be executed by PHP interpreter (here is a description).
So, I was wondering - is there a way to strip malicious code from images? would recoding images with GD or ImageMagick work?
Actual images will not contain code. But there's nothing stopping someone from trying to get an "image" file uploaded, and then try and get it to execute.
Your interpreters (Perl, PHP, whatever) should be set up so that they only execute certain file types (i.e. .php or .php5). There's no reason Perl or PHP should be parsing image files.
Just use the following common sense to protect yourself:
1) Verify the mime type of the document
2) Enforce policies that only allow uploading files of a certain extension
3) Don't accept filenames at face value. Generate your own internal file name and use a database table to keep the mapping.
4) If you're truly paranoid, find some code to check that the byte signatures are valid for the given file type upload.
You should configure your webserver not to allow your image filename extensions to get interpreted by PHP. As showed on the page linked in the question, images can contain PHP code. Always check the filename extension against a whitelist:
<?php
$whitelist = '/\.(?:jpe?g|png|gif)$/i';
if (!preg_match($whitelist, $_FILES['userfile']['name'])) {
echo "Bad filename extension.";
exit;
}
$uploaddir = 'uploads/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
echo "File is valid, and was successfully uploaded.";
} else {
echo "File uploading failed.";
}
?>