/    Sign up×
Community /Pin to ProfileBookmark

Why My Php Fail To Detect File Type Or File Extension ?

Folks,

I am building a membership script for 21 months now!!! That long!!!
Anyway, I need members to say infront of their cams a few things and then upload the vid file to the site (from the confirm_id.php page) where the member’s sponsor (recruiter) will get the video copy to check if it’s the real person with the real personal details or not. If true details, then sponsor verifies the member account. Else, unverifies it.
Now, I been testing my code. I uploaded an mp4 file. That should be ok but I get echoed:
“There was a problem uploading your video file $file_name! Make sure your file is an MP4 or a WAV file. You may try again now.”
Why ?

Not pasting the whole script as really long. Would do your head in.
Only pasting relevant part:

[code]
if($_SERVER[“REQUEST_METHOD”] == “POST”)
{
if(!isset($_FILES[“id_verification_video_file”])) //REtype
{
echo “no isset”;
}
else
{
$id_verification_video_file = $_FILES[‘id_verification_video_file’]; //REtype
//Feed Id Video Verification File Upload Directory Path.
$directory_path = “uploads/videos/id_verifications/”;
//Make Directory under $user in ‘uploads/videos/id_verifications’ Folder.

if(!is_dir(“$directory_path” . “$user”))
{
$mode = “0777”;
mkdir(“$directory_path” . “$user”, “$mode”, TRUE); //Thanks Requinix for my “$mode” typo hint.
}

//Grab Uploading File details.
$Errors = Array(); //SHOULD I KEEP THIS LINE OR NOT ?
$file_name = $_FILES[“id_verification_video_file”][“name”];
$file_tmp = $_FILES[“id_verification_video_file”][“tmp_name”];
$file_type = $_FILES[“id_verification_video_file”][“type”];
$file_size = $_FILES[“id_verification_video_file”][“size”];
$file_error = $_FILES[‘id_verification_video_file’][‘error’];

//Grab File Extension details.
$file_extension = pathinfo($file_name, PATHINFO_EXTENSION);
if(file_exists(‘$directory_path’ . ‘$user/’ . ‘$file_name’))
{
$Errors[] = “Error: You have already uploaded a video file to verify your ID!”;
exit();
}
else
{
//Feed allowed File Extension(s).
$allowed_file_extensions = array(“mp4” => “video/mp4″,”wmv” => “video/wmv”);
//Feed allowed file size.
$max_file_size_allowed_in_bytes = 1024*1024*100; //Allowed limit: 100MB.
$max_file_size_allowed_in_kilobytes = 1024*100;
$max_file_size_allowed_in_megabytes = 100;

$max_file_size_allowed = “$max_file_size_allowed_in_bytes”; //RETYPE

//Verify File Extension.
if(!array_key_exists($file_extension,$allowed_file_extensions)) die(“Error: Select a valid video file format. Select an MP4 or WAV file.”);
//Verify MIME Type of the file.
elseif(!in_array($file_type,$allowed_file_extensions))
{
echo “Error:<font size =’5′ font color =’red’><b>There was a problem uploading your video file $file_name! Make sure your file is an MP4 or a WAV file. You may try again now.</b></color></size>”; //THANKS TO REQUINIX FOR BRINNGING IT TO MY ATTENTION I AM STILL PROCESSING THE SCRIPT AFTER THIS LINE WHEN I SHOULD NOT.
exit();
}
//Verify File Size. Allowed Max Limit: 100MB.
elseif($file_size>$max_file_size_allowed) die(“Error: Your Video File Size is larger than the allowed limit of: $max_file_size_allowed_in_megabytes.”); //Fixed variable name typo. Thanks to Requinix & Simon JM.
//Move uploaded File to newly created directory on the server.
move_uploaded_file(“file_tmp”,”$directory_path” . “$user/” . “$file_name”);
//Notify user their File was uploaded successfully.
echo “<font size =’5′ font color =’red’><b>Your Video File “$file_name” has been uploaded successfully! You will get notified once your Id has been verified successfully.</b></color></size>”;

[/code]

Can you spot my coding error ?
Any other errors ?
How-about you show me code sample how you’d do it better and simpler with as much less lines of codes as possible ? ?

to post a comment
PHP

12 Comments(s)

Copy linkTweet thisAlerts:
@rootNov 19.2018 — As found on the [url=http://php.net/manual/en/function.pathinfo.php]PHP.net[/url] web site &lt;?php
$path_parts = pathinfo('/www/htdocs/inc/lib.inc.php');

echo $path_parts['dirname'], "n";
echo $path_parts['basename'], "n";
echo $path_parts['extension'], "n";
echo $path_parts['filename'], "n"; // since PHP 5.2.0
?&gt;
Copy linkTweet thisAlerts:
@site-developerauthorNov 20.2018 — @root#1598003

I was suggested this:

http://php.net/manual/en/function.mime-content-type.php

Was told:

"The "type" in $_FILES is not reliable.

If you want to check the type then you have to find out what the type is by yourself, like by using fileinfo. Or you can not check the type and rely on the extension instead."

http://php.net/manual/en/book.fileinfo.php

When I asked if I should try this:

http://php.net/manual/en/function.mime-content-type.php

was told:

"If you can get it to work, yes. PHP can't always find the magic file, which defines what types go to what files.

If it doesn't work then you'll need the finfo_* functions and probably your own magic file downloaded from somewhere (check user comments for help there).".

root, what do you make out of all this ?
Copy linkTweet thisAlerts:
@rootNov 21.2018 — http://php.net/manual/en/features.file-upload.post-method.php

Notice the naming convention of array $_FILES.
Copy linkTweet thisAlerts:
@site-developerauthorNov 25.2018 — @root#1598133

Ok.

I grabbed the code found in the manual link you provided. Modified it a little. Customized it.

<i>
</i>&lt;?php
//Required PHP Files.
include 'configurations_site.php'; //Required on all webpages of the site. Must include here too. Else, conn.php data would not be found. conn.php residing in site_configurations.php.
include 'header_site.php'; //Required on all webpages of the site.
include 'header_account.php'; //Required on all webpages of the account.
include 'sessions.php'; //Required on all webpages of the site.

&lt;?php

//ERROR REPORTING CODES.
declare(strict_types=1);
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);


if($_SERVER["REQUEST_METHOD"] == "POST")
{
//Check whether the file was uploaded or not without any errors.
if(!isset($_FILES["userfile"]) &amp;&amp; $_FILES["userfile"]["Error"] == 0)
{
$Errors = Array();
$Errors[] = "Error: " . $_FILES["userfile"] ["ERROR"];
print_r($_FILES); ?&gt;&lt;br&gt;&lt;?php
print_r($_ERRORS);
exit();
}
else
{
// In PHP versions earlier than 4.1.0, $HTTP_POST_FILES should be used instead
// of $_FILES.

<i> </i> $uploaddir = 'uploads/videos/id_verifications/';
<i> </i> $uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

<i> </i> echo '&lt;pre&gt;';
<i> </i> if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile))
<i> </i> {
<i> </i> echo "File is valid, and was successfully uploaded.n";
<i> </i> }
<i> </i> else
<i> </i> {
<i> </i> echo "Possible file upload attack!n";
<i> </i> }

<i> </i> echo 'Here is some more debugging info:';
<i> </i> print_r($_FILES);

<i> </i> print "&lt;/pre&gt;";
<i> </i> }
<i> </i>}
?&gt;

&lt;!-- The data encoding type, enctype, MUST be specified as below --&gt;
&lt;form enctype="multipart/form-data" action="" method="POST"&gt;
&lt;!-- MAX_FILE_SIZE must precede the file input field --&gt;
&lt;input type="hidden" name="MAX_FILE_SIZE" value="100000000" /&gt;
&lt;!-- Name of input element determines name in $_FILES array --&gt;
Send this file: &lt;input name="userfile" type="file" /&gt;
&lt;input type="submit" value="Send File" /&gt;
&lt;/form&gt;


Instead of getting echoed via THEN: "File is valid, and was successfully uploaded.".

I get echoed via ELSE: "Possible file upload attack!".

Why ?

root, I am trying to startover using the codes from the manual.

Do you mind modifying at to the simplest barebone so only WAV & MP4 and max 100MB size files can be uploaded ? Error only should occur if files are not these just mentioned.
Copy linkTweet thisAlerts:
@site-developerauthorNov 25.2018 — root & ginerjm,

On this link, which code would you go for and why that particular one over the others if you wanted your script to check whether the user has uploaded the right type of file or not. Like mp4 ?

http://php.net/manual/en/function.mime-content-type.php

@root, do remember my previous post. Thanks! ?

I will try unlearning a little and then relearning again from your and the manual's examples.

Cheers!
Copy linkTweet thisAlerts:
@rootNov 26.2018 — You want to get the file extension, so I told you how, you now comment on mime_types, so here http://php.net/manual/en/function.mime-content-type.php

I would IMHO check the following...

file extension - if the file extension says its an image, then it should match one of the mime_image_types and you would check that you have one matching.

THEN I would get the files permissions, check that the image has not got any settings that allow it to execute as it could be an image with embedded code like in GIF's, so checking the executable state of the file, is a file that simply read/write or is it read/write and execute? if the file perms flags are not correct, the file should be treated as suspect, then you can run a routine that zips the file up to neutralise any thread, store it where people can't get to it so you can see the file.

or you could just purge it to be 100% sure of no possible hack attempt.

Additional:

You should trawl PHP.net because you find ready made functions like http://php.net/manual/en/function.is-executable.php to test if the file is executable. if file permissions isn't enough.
Copy linkTweet thisAlerts:
@site-developerauthorNov 27.2018 — You know I am really getting spooked reading articles how malicious files can be uploaded to your site.

https://www.acunetix.com/websitesecurity/upload-forms-threat/

Anyway, with php, how to do following found here:

https://www.computerweekly.com/answer/File-upload-security-best-practices-Block-a-malicious-file-upload

  • * The application should use client- or server-side input validation to ensure evasion techniques have not been used to bypass the whitelist filter. These evasion techniques could include appending a second file type to the file name (e.g. image.jpg.php) or using trailing space or dots in the file name.

  • * The application should set a maximum length for the file name, and a maximum size for the file itself.

  • * The directory to which files are uploaded should be outside of the website root.

  • * All uploaded files should be scanned by antivirus software before they are opened.


  • Q1. How can you get your webform to upload the user's video file outside the root folder and then how can you call that video file on a webpage from the "outside" section so the page displays the video to page visitors ?

    Q2. What max length in file name I should allow ?

    Q3. How to prevent evasion techniques that could include appending a second file type to the file name (e.g. image.jpg.php) ?

    Folks, I am really looking into this video uploading thing for the reasons mentioned in my original post to see what the account members (membership site or social network) look like and to deter them uploading malicious files using their accounts because they wouldn't want to do illegal things with their web proxy account knowing I know who they are and what they look like and can easily forward their videos (that identify them) to their authorities.

    But, all this video uploading php feature with so many security issues is starting to get to me. Any other way I can get an account holder's ID verification so they think twice before watching anything illegal with my web proxy via their accounts ?

    I am now considering to only allow users to signup with gmail, hotmail and yahoomail as these verify users getting users to confirm their mobile fone numbers for IDying purposes.

    Right now, my reg.php asks for user's website domain and tries identifying the users via their domain names (can find the domain owner via whois.net).

    Right now, my reg.php asks for user's website domain and tries identifying the users via their domain names (can find the domain owner via whois.net).

    Do you think I am worrying too much and should forget trying to get users to upload vids of themselves and identifying them through gmail, hotmail and yahoomail is enough ? Maybe, identifying them through their domain names is enough ? I just want to make sure people don't signup using false details or register hundreds of fake accounts and then start browsing illegal sites with their accounts using my web proxy.

    Any suggestions or advice ?

    What would you do in my position ?

    This is the only obstacle standing on my way from finishing this membership site php script project that took me 22 mnths to learn php on this field and build the script. 22 months! When am I gonna finish this project and move-onto pdo ? Already 1.5yrs late!

    EDIT:

    No good advice here:

    https://stackoverflow.com/questions/6498230/preventing-fake-accounts

    Believe me people, I can build .exe bots to auto register unlimited fake accounts. But, I don't build crook bots. Hence, need foolproof methods to atleast foil bots I can build and the methods mentioned on the stackoverflow link above can be bypassed!

    Now, hunting here:

    https://www.google.com/search?q=how+to+prevent+fake+accounts+%3F&oq=how+to+prevent+fake+accounts+%3F&aqs=chrome..69i57.15912j0j7&sourceid=chrome&ie=UTF-8
    Copy linkTweet thisAlerts:
    @rootNov 28.2018 — > @site-developer#1598326 The application should use client- or server-side input validation to ensure evasion techniques have not been used to bypass the whitelist filter. These evasion techniques could include appending a second file type to the file name (e.g. image.jpg.php) or using trailing space or dots in the file name.

    Where did you get that from?

    YOU NEVER use CLIENT-SIDE Validation, YOU ALWAYS use SERVER-SIDE validation.

    You test the mime type, check if it is executable and can test the file permissions as well as that you can quarantine an incoming file when you have had it uploaded and moved, thats when you alter the extension if it is suspect.
    Copy linkTweet thisAlerts:
    @site-developerauthorNov 28.2018 — @root#1598339

    Got it from here ofcourse:

    https://www.computerweekly.com/answer/File-upload-security-best-practices-Block-a-malicious-file-upload
    Copy linkTweet thisAlerts:
    @rootNov 28.2018 — Some of that article has only said what I was saying 10 years or more ago and people laughed it off....

    Never rely on client-side validation.

    JavaScript is unreliable in this area, you only need the client to turn off javascript. your form validation is now dead in the water.

    ALWAYS SERVER-SIDE for validation.

    HTML5 is more robust then JavaScript, use those form inputs and you are making it harder for people to do things like input or force data into fields that they shouldn't have access to or in many cases, your site is targeted by a push client and your server gets force fed chunks of data in an attempt to break the server or the script.

    SO... never rely in JavaScript to do the job...

    Copy linkTweet thisAlerts:
    @site-developerauthorMar 14.2019 — root,

    Trying the finfo() now.

    http://php.net/manual/en/function.finfo-buffer.php

    Now, when I upload a single video file I get the script spitting:

    video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4 video/mp4

    Why that many times and not just once "video/mp4"?

    <i>
    </i>$file_name = $_FILES["id_verification_video_file"]["name"];
    $file_tmp = $_FILES["id_verification_video_file"]["tmp_name"];
    $file_type = $_FILES["id_verification_video_file"]["type"];
    $file_size = $_FILES["id_verification_video_file"]["size"];
    $file_error = $_FILES['id_verification_video_file']['error'];

    $finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
    foreach (glob("*") as $filename) {
    echo finfo_file($finfo, $file_name) . "n";
    }
    finfo_close($finfo);
    }
    }


    What does the "glob("*") " mean ?

    Found it in the manual:

    http://php.net/manual/en/function.finfo-file.php
    Copy linkTweet thisAlerts:
    @site-developerauthorMar 14.2019 — Does anyone know the answer to my question in my previous post ?
    ×

    Success!

    Help @site-developer spread the word by sharing this article on Twitter...

    Tweet This
    Sign in
    Forgot password?
    Sign in with TwitchSign in with GithubCreate Account
    about: ({
    version: 0.1.9 BETA 4.23,
    whats_new: community page,
    up_next: more Davinci•003 tasks,
    coming_soon: events calendar,
    social: @webDeveloperHQ
    });

    legal: ({
    terms: of use,
    privacy: policy
    });
    changelog: (
    version: 0.1.9,
    notes: added community page

    version: 0.1.8,
    notes: added Davinci•003

    version: 0.1.7,
    notes: upvote answers to bounties

    version: 0.1.6,
    notes: article editor refresh
    )...
    recent_tips: (
    tipper: @Yussuf4331,
    tipped: article
    amount: 1000 SATS,

    tipper: @darkwebsites540,
    tipped: article
    amount: 10 SATS,

    tipper: @Samric24,
    tipped: article
    amount: 1000 SATS,
    )...