Only allow image files to be uploaded to my server with PHP - php

I'm trying to make a script in which I only allow .png, .jpeg and .gif files to be uploaded, based on MIME types. What I have so far is this:
if(file_exists($root."/upload/gallery/".$_FILES["image"]["name"]))
{
$filename = explode(".",$_FILES['image']['name']);
$randomnumber = rand(0, 10000);
$imageName = $filename[0].$randomnumber.".".$filename[1];
}
else
{
$imageName = $_FILES['image']['name'];
}
$image = mysql_real_escape_string(htmlspecialchars("/upload/gallery/".$imageName));
$allowed = array('image/jpeg', 'image/png', 'image/gif');
if(in_array($_FILES['image']['name'], $allowed)){
echo "Allowed!";
die;
}
else {
echo "Not allowed!";
die;
}
I was almost certain this should work. But it always echoes Not allowed! while I choose files with the correct MIME type, what am I doing wrong here? The code includes a check for files in my upload folder that already have the same name and if so adds a random number to the filename.

You are comparing the allowed list against the file name, not the type.
The type of the file will be contained in an array of applicable types in:
$_FILES['image']['type']

Related

In Codeigniter How to check if the uploaded file is actually a pdf or jpg or png?

In Codeigniter How to check if the uploaded file is actually a pdf or jpg or png? Because, if we upload an .exe file with .pdf extension then also it gets uploaded without any problem. So, it there a proper way to actually check the file and its content to be able to determine whether it is actually a pdf or exe. Because with just the file extension anything can be uploaded. Please, help me find a proper solution for this. Is there any native php function through which we can achieve this. If so a sample code might be helpful.
you can use mime_content_type() function which is in built in php it provides actual content type even if the extension is changed
php docs
<?php
echo mime_content_type('abcd.pdf') //application/pdf
?>
checking mime_content_type while uploading
$mimetype = mime_content_type($_FILES['file']['tmp_name']);
if(in_array($mimetype, array('image/jpeg', 'image/gif', 'image/png'))) {
move_uploaded_file($_FILES['file']['tmp_name'], '/whatever/something/imagedir/' . $_FILES['file']['name']);
echo 'OK';
} else {
echo 'It is not an image';
}
You need to check real file type and given file type like this:
$config['upload_path'] = './uploads/';
$config['allowed_types'] = 'gif|jpg|png|pdf';
$this->load->library('upload', $config);
$file = $_FILES['userfile'];
// given file type
$gftype=pathinfo($file['name'], PATHINFO_EXTENSION);;
// real file type
$rftype = explode('/',mime_content_type($file['tmp_name']))[1];
if($gftype === $rftype){
if (! $this->upload->do_upload('userfile')){
echo "Error";
}else{
echo "Success";
}
}else{
echo 'This is not real extension';
}

Image and PDF file upload validation in PHP

Im creating a web app that manages staff records, one of the features allows staff to upload copies of their qualifications. Because many scanners output into different file types i need to be able to validate that the uploaded files are either a PDF or one of the many different image file types.
Im aware of the MIME validation method and have used this but as it is relatively easy to hack I'm looking for a more secure method to supplement it with.
The relevant code from the config file where constants are stored
// Set the file types allowed to be uploaded
define('FILETYPEALLOWED', serialize (array ('image/pjpeg', 'image/jpeg', 'image/JPG', 'image/X-PNG', 'image/PNG', 'image/png', 'image/x-png' ) ));
The code that handles the form
//If a file was uploaded, Move the uploaded file
IF (isset($_FILES['upload'])) {
$allowed = unserialize (FILETYPEALLOWED);
$fileinfo = finfo_open (FILEINFO_MIME_TYPE);
//IF file type is allowed
IF (in_array($_FILES['upload'] ['type'], $allowed )) {
move_uploaded_file($_FILES['upload'] ['tmp_name'], UPLOADS . $_FILES['upload'] ['name'] );
} else {
//Add an error to the $errors array
$errors[] = 'The file type is not allowed.';
}
//Delete the temporary file
IF (file_exists ($_FILES['upload'] ['tmp_name']) && is_file($_FILES ['upload'] ['tmp_name'])) {
unlink ($_FILES ['upload'] ['tmp_name']);
echo '<p>The temp file been file.</p>';
}
} else {
print '<p>no file was uploaded</p>';
}

How to validate multiple uploaded file using php?

I am using PHP to upload multiple file to the database. So when I check file extension its always showing me my given error message even if file extension is correct:
File type is not allowed, We accept only .jpg, .png and .gif extension
file
Here is the validation :
$total = count($_FILES['client_doc']['name']);
for($i=0; $i<$total; $i++) {
$file_name = htmlspecialchars($_FILES['client_doc']['name'][$i]);
$file_tmp = htmlspecialchars($_FILES['client_doc']['tmp_name'][$i]);
$file_size = htmlspecialchars($_FILES['client_doc']['size'][$i]);
$file_ext = explode('.', $file_name);
$file_ext = strtolower(end($file_ext));
$allowed_type = array('jpg', 'jpeg', 'gif', 'png');
}
if(!empty($file_name)) {
if(!in_array($file_ext, $allowed_type)) {
$msg[] = 'File type is not allowed, We accept only .jpg, .png and .gif extension file';
$msg['error'] = true;
}elseif($file_size > 2097152) { // only 2 mb size is allowed
$msg[] = 'Uploaded file name must be less than 2MB';
$msg['error'] = true;
}
}
I've tested your code by giving the $file_name variable test.png value and it works fine. Are you sure your file form works correctly? Try to echo $file_name's at the end of for loop and check if there's any output.
Another tips:
Do you want to validate all the files? As far as I'm concerned your current code validates only the last file - you iterate through all the files, but you overwrite variables storing file's data. In order to validate all the elements you have to put your condition inside the for loop.
Because your $allowed_type is a constant, you don't have to overwrite it inside the loop.

move_uploaded_file is making a file called 'array'?

the following piece of code recognizes the image through getimagesize() but then when i try to move the file to an uploaded folder it moves the file there but says it's an array? im confused because im not setting any variables as an array?
<?php
//simple image check using getimagesize() instead of extensions
if($_FILES){
$empty_check = getimagesize($_FILES['file']['tmp_name']);
if(empty($empty_check)){
echo 'this is not an image';
}
else{
echo 'you have uploaded ' . explode('.',$_FILES['file']['name'])[0].'
and it is a ' . explode('.',$_FILES['file']['name'])[1].'.';
//an example of how i would extract the extension
$target = "C:\\xampp\\htdocs";
move_uploaded_file($_FILES['file']['tmp_name'], $target.'\\'.$_FILES['file']);
}
}
?>
$_FILES['file']
is an array, you're trying to use it as the target filename;
comment of deceze.
Echo the file you want to move/save, then you should see what he mentioned..
When using move_uploaded_file you get to pick the filename, so you can pick anything you want.
When you upload the file, its put into a temporary directory with a temporary name, move_uploaded_file() allows you to move that file and in that you need to set the name of the file as well.
Use this coding for multiple file uploading....
//For Multiple file uploading
if (isset($_FILES['photo']) != "") {
$errors = array();
foreach($_FILES['photo']['tmp_name'] as $key = > $tmp_name) {
$file_name = $_FILES['photo']['name'][$key];
$file_size = $_FILES['photo']['size'][$key];
$file_tmp = $_FILES['photo']['tmp_name'][$key];
$file_type = $_FILES['photo']['type'][$key];
//change the image extension as png
$fileExt = "png";
$photorename[$key] = strtolower($property_code.
'_'.$key.
'.'.$fileExt);
if ($file_size > 2097152) {
$errors[] = 'File size must be less than 2 MB';
}
//Path of Uploading file
$target = "images_property";
if (empty($errors) == true) {
if (is_dir($target) == false) {
mkdir("$target", 0700); // Create directory if it does not exist
}
if (file_exists("$target/".$photorename[$key])) {
unlink("$target/".$photorename[$key]);
}
move_uploaded_file($file_tmp, "$target/".$photorename[$key]);
} else {
print_r($errors);
}
}
if (empty($errors)) {
echo "Success";
}
}

Restrict file upload to just jpegs with php

Please can someone help? I have the following code which uploads a file to my server and renames it to whoever the logged in user is. For example the user 'coca-cola-lover' uploads a jpeg - the script would also rename the jpeg 'coca-cola-lover.jpg'.
My problem is that I need it to limit the upload to just jpegs - and also limit the file size to 2mb.
Please help - I was trying to find a solution all night.
Thanks in advance
// Your file name you are uploading
$file_name = $HTTP_POST_FILES['ufile']['name'];
$username = $row_Recordset1['username'];
$ext = end(explode('.', $file_name));
$renamed_file_name = $username;
$new_file_name=$renamed_file_name.'.'.$ext;
//set where you want to store files
//in this example we keep file in folder upload
//$new_file_name = new upload file name
//for example upload file name cartoon.gif . $path will be upload/cartoon.gif
$path= "../sites/images/users/".$new_file_name;
if($ufile !=none)
{
if(copy($HTTP_POST_FILES['ufile']['tmp_name'], $path))
{
echo "Successful<BR/>";
//$new_file_name = new file name
//$HTTP_POST_FILES['ufile']['size'] = file size
//$HTTP_POST_FILES['ufile']['type'] = type of file
echo "File Name :".$new_file_name."<BR/>";
echo "File Size :".$HTTP_POST_FILES['ufile']['size']."<BR/>";
echo "File Type :".$HTTP_POST_FILES['ufile']['type']."<BR/>";
}
else
{
echo "Error";
}
}
getimagesize tells you what format the file is in
as per bgy's comment, you should also force the file extension to be what you want:
$new_file_name=$renamed_file_name.'.'.$ext; // wrong, uses data from the client
$new_file_name=$renamed_file_name.'.jpg'; // ok, just what we want
never trust and never use filenames provided by the client.
I would recommend exif_imagetype:
<?php
if (exif_imagetype('image.gif') != IMAGETYPE_GIF) {
die(The picture is not a gif');
}
For details see here: http://php.net/manual/en/function.exif-imagetype.php
You can use any of the four to detect a mimetype of the file:
finfo_open (by default enabled as of 5.3)
getimagesize (requires enabled GD)
exif_imagetype (requires enabled Exif)
mime_content_type (deprecated as of 5.3)
You can also limit the MimeType from the FileUpload element, but since this is client-side code, it can easily be removed by malicious users (and it's also buggy across browsers):
<input type="file" name="picture" id="picture" accept="image/jpeg"/>
For further information on how to handle file uploads with PHP (including limiting file size), check the manual.
There is also a lot of very similar questions on Stack Overflow already, one being:
Check picture file type and size before file upload in php
You restrict the size via the normal mechanisms, but you'll need to use the fileinfo functions to determine the filetype after uploading.
A few advices for the current code
Use $_FILES instead of $HTTP_POST_FILES.
If you need to get file extensions use $extension = pathinfo($filename, PATHINFO_EXTENSION);.
Use is_uploaded_file and move_uploaded_file.
Don't relay on $_FILES['file']['type'] - it can be modified by user.
Indent your code.
If you want to limit file upload to the following requirements:
Filesize: max 2mb.
File type: image/jpeg
Do something like that:
$tmpName = $_FILES['file']['tmp_name'];
if (file_is_uploaded($tmpName) {
$filesize = fielsize($tmpName);
$mimeType = exif_imagetype('image.gif');
if ($filesize <= 2 * 1024 * 1024 && $mimeType == IMAGETYPE_JPEG) {
$filename = $USERNAME . '.jpg';
if (move_uploaded_file($tmpName, $filename) == false) {
// sth goes wrong
}
} else {
die('Invalid.');
}
}

Categories