Hello all!

I'm currently writing a form for users to upload their resume as well as some other form fields. I was just curious if my upload script has proper validation to ensure it's a document instead of .exe, .jpg, etc. I've read that checking just the extension isn't good enough so I was wondering how to truly check to make sure the file is what's expected, and if I am on the right track.

I've removed a lot of the irrelevant code to keep the script at a reasonable length, including all the ELSE portions of the IF statements with their corresponding error handling.

if(isset($_POST['submit']))
{
    //Validates the text fields of the upload form
    $valid = validate_application($_POST);
    if($valid['response'])
    {
        if($_FILES['resume']['error'] == 0)
        {
            //Make sure the file smaller than 5MB
            if($_FILES['resume']['size'] < 5000000)
            {
                $allowed = array('.doc', '.docx', '.pdf');
                $filename = $_FILES['resume']['name'];
                $extension = substr($filename, strpos($filename, '.'), strlen($filename) - 1);
                $mimetype = $_FILES['resume']['type'];

            /**
             * .doc  = application/msword 
             * .docx = application/vnd.openxmlformats-officedocument.wordprocessingml.document
             * .pdf  = application/pdf
             */

            if(in_array($extension, $allowed))
            {
                if(($extension == '.doc' && $mimetype == 'application/msword')
                   || ($extension == '.docx' && $mimetype == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document')
                   || ($extension == '.pdf' && $mimetype == 'application/pdf')
                  )
                {    
                    //A bunch of ternary operators checking to make sure the various form elements exist

                    //Uploads the file into the directory
                    $overrides = array('test_form' => false);
                    require_once(ABSPATH.'wp-admin/includes/file.php');
                    $file = wp_handle_upload($_FILES['resume'], $overrides);

                    //Make sure there were no errors uploading the file itself
                    if(!isset($file['uploads_error_handler']))
                    {
                       //Insert form information into the database
                       echo '<span class="success">Thank you for applying for <strong>'.get_the_title().'</strong>. We now have your resume on file.</span>';
                    }
                }
            }
        }
    }
}
}

Any tips or insight would be appreciated. Thanks! 🙂

                    $filename = $_FILES['resume']['name'];
                    $extension = substr($filename, strpos($filename, '.'), strlen($filename) - 1);
                    $mimetype = $_FILES['resume']['type'];
    

    The problem is that these rely on information supplied by the client (i.e. the person submitting the file).

    For a more reliable assessment you actually need to look at the file itself. The [man]Fileinfo[/man] extension is built for this; it will look at the file and decide its mime type.

    It may have a problem with .docx (I haven't tried), because a .docx document is also a .zip file. If FileInfo reports that, you could use [man]Zip[/man] functions to look inside for a file named [font=monospace][Content_types].xml[/font] and a subdirectory named [font=monospace]word[/font].

      That's definitely the better way, but it seems the Fileinfo extension, namely the finfo_file() function, is available in PHP 5.3.0+. I'll have to double-check but I am not sure if my development environment has a PHP version that high. I also cannot ensure that the server that this script will be going onto will have a PHP version that high either. This script is part of a client's project and while we can recommend to them certain hosting (and we do), in the end of course they decide who they want to go with. I know for example my GoDaddy hosting only offers PHP 5.2.

      So I guess my question is, is there an alternative or a "next best" method for <5.3.0?

        Write a Reply...