Php secure file upload script (Block Backdoor Shell Upload)

Start Chatting Already [No Registration Required]

Enter The Chat

This will take you to the chat room you are looking for.

A poorly written file upload script can be exploited to upload a backdoor shell to your server. A backdoor shell can read & modify your server’s files. It can be a nightmare for any developer as it takes an attacker a ready made file(c99/ r57/ p0wny) & an upload button to steal your database credentials and various other data.

Secure file upload script example

<?php
$uploadResult = acceptUploadedFile('uploads', 'picture', 1500);//Accept images as large as 1.5 MB
if ($uploadResult['status']) {
    echo "Uploaded successfully!";
} else {
    echo "Upload failed due to reason: " . $uploadResult['reason'];
}

function acceptUploadedFile($targetDir, $fieldName, $sizeKB = 500)
{
    /*
     Re-usable function for secure image upload.
     $targetDir: folder where you keep uploaded images
     $sizeKB: Max size of image in KBs. Images larger than this will be rejected
     $fieldName: Should contain name parameter of input field (<input type='upload' name='picture'>)
    */
    global $_FILES;
    $target_file = $targetDir . basename($_FILES[$fieldName]["name"]);
    $uploadOk = 1;
    $imageFileExtension = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));
    $reason = '';

    // Check if image file is a actual image or fake image
    if (isset($_POST["submit"])) {
        $check = getimagesize($_FILES[$fieldName]["tmp_name"]);
        if ($check !== false) {
            //echo "File is an image - " . $check["mime"] . ".";
            $uploadOk = 1;
        } else {
            $reason = "File is not an image.";
            $uploadOk = 0;
        }
    }

    // Check if file already exists
    if (file_exists($target_file)) {
        $reason = "Sorry, file already exists.";
        $uploadOk = 0;
    }

    // Check file size
    if ($_FILES["fileToUpload"]["size"] > $sizeKB * 1000) {
        $reason = "Sorry, your file is too large.";
        $uploadOk = 0;
    }

    // Allow certain file formats
    $acceptedFileTypes = ["jpg", "png", "jpeg", "gif"];
    if (array_search($imageFileExtension, $acceptedFileTypes) === false) {
        $reason = "Sorry, only " . implode(', ', $acceptedFileTypes) . " files are allowed.";
        $uploadOk = 0;
    }

    // Check if $uploadOk is set to 0 by an error
    if ($uploadOk == 0) {
        return ['status' => false, 'error' => $reason];
    } else {
        // if everything is ok, try to upload file
        if (move_uploaded_file($_FILES[$fieldName]["tmp_name"], $target_file)) {
            return ['status' => true];
        } else {
            return [
                'status' => false,
                'error' => 'move_uploaded_file',
                'debug_assistance'=>[
                    //Do not output debug_assistance information to end users. Its for developer only.
                    'upload_directory'=>$targetDir,
                    'upload_directory_exists'=>file_exists($targetDir),
                    'is_writable'=>is_writable($targetDir),
                    'is_readable'=>is_readable($targetDir),
                ]
            ];
        }
    }
    /*
     * This function uses code from https://www.w3schools.com/php/php_file_upload.asp
     * If your code or a plugin uses ImageMagick to resize/crop images, please update ImageMagick to latest version otherwise, you might be vulnerable to https://imagetragick.com/

     * Debug notes:
     * Error move_uploaded_file -> This means your upload directory is not writable. You need to login to your file manager/ terminal,
     *                       browse to the directory containing your upload directory and do chmod +777 upload_folder_name
     */
}

Also read this article and makes sure to check its FAQ section about shell upload: Prevent backdoor shell upload attack with Cloudflare

Leave a Reply

Your email address will not be published. Required fields are marked *