How to detect a file type in PHP

Note: This is not a tutorial on how to upload files in PHP

One of the major challenges when it comes to processing file uploads in PHP is determining the correctness of the file type. There are different ways to check the type of file uploaded if it's an image or pdf or any other type of file, but the downside to some of these methods is that the file uploaded can be spoofed.

Spoofing is when someone or something pretends to be something else in an attempt to gain a victim's confidence, get access to a system, steal data, or spread malware

This gives a malicious user the ability to upload a script that could grant them access to your application by masking the extension of such a file, which results to your application being hacked.

We'll look at how to prevent this by using PHP in-built functions finfo_open() and finfo_file().

First, we'll create a basic HTML page index.html containing a form to select files for upload.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Detecting File Types</title>
</head>

<body>
    <form method="post" action="process_upload.php" enctype="multipart/form-data">
        <input type="file" name="file">
        <input type="submit" name="submit" value="Submit">
    </form>
</body>

</html>

Next, we'll create the script process_upload.php that handles the data sent from the form.

<?php
if (isset($_POST['submit']) && isset($_FILES['file'])) {
    $file_name = $_FILES['file']['name'];
    echo $file_name;
}
?>

From the image which shows the output of the above script, the name of the file selected is displayed when the form is submitted.

Next, we'll be getting the file type using finfo_open and finfo_file

<?php
if (isset($_POST['submit']) && isset($_FILES['file'])) {
    $file_name = $_FILES['file']['name'];
    $temp = $_FILES['file']['tmp_name'];

    // * returns the mime type
    $mime = finfo_open(FILEINFO_MIME_TYPE);

    // * Returns info about a file
    $type = finfo_file($mime, $temp);

    echo $type;
}

The major advantage of using this method to get the file type of a document is that it reads the content of the document to determine what type of file it is. So if a document that originally has an extension of txtis renamed to an image extension like png or jpg, it's still able to detect that document with its original extension of txt.

Conclusion

With this method, the developer is able to prevent his application from being hacked via spoofing by properly checking the type of file being uploaded.