Skip to main content
Tweeted twitter.com/StackCodeReview/status/1075405571237519360
edited tags
Link
200_success
  • 144.1k
  • 22
  • 188
  • 473
Source Link

PHP remote upload security

I need to upload images to a remote HTTP server from a local script. The image name format is {32-char MD5}.jpg. Server directory format is 6c/d3/6cd3556deb0da54bca060b4c39479839.jpg. So, for example, if I upload the image called 6cd3556deb0da54bca060b4c39479839.jpg, it should be available at https://example.com/6c/d3/6cd3556deb0da54bca060b4c39479839.jpg.

The local script basically does a HTTPS multipart/form-data POST request with the "file" and "password" fields to a remote server (https://example.com/up.php).

Remote server has a PHP script (up.php) which checks if the "password" is correct and then either allows file uploading or disallows it.

Is this script secure? What can go wrong?

This is the code I use on the server. It checks password against SHA-512 hash and then checks if the filename extension is ".jpg".

<?php
// Upload Script
//
// You need to post "file" and "password", which is checked
// against using SHA-512

// Check if the password is correct
$password_hash = "128-characters long SHA-512 string here";
if (hash("sha512", $_POST["password"]) != $password_hash) {
    http_response_code(403);
    echo "403 Access Denied";
    exit(1);
}

if(!empty($_FILES["file"])) {
    // Check if the filename extension is ".jpg",
    // otherwise deny uploading
    $file_parts = pathinfo($_FILES["file"]["name"]);
    if ($file_parts["extension"] != "jpg") {
        http_response_code(500);
        echo "Incorrect File Extension";
        exit(1);
    }

    // Filename of the file being uploaded
    $filename = $_FILES["file"]["name"];

    // Build a directory path
    $tmp_a = mb_substr($filename, 0, 2); // First 2 chars of a filename
    $tmp_b = mb_substr($filename, 2, 2); // 3 to 4 chars of a filename
    $tmp_c = $filename;
    $directory = "$tmp_a/$tmp_b";
    // Full path to the file including the directory
    $full_path = "$directory/$filename";

    // If the directory doesn't exist, then create it
    if (!file_exists($directory)) {
        mkdir($directory, 0755, true);
    }

    // Upload the file
    if (move_uploaded_file($_FILES["file"]["tmp_name"], $full_path)) {
        echo "Success";
    } else {
        http_response_code(500);
        echo "Something went wrong";
        exit(1);
    }
}