Manera segura de cargar imágenes php y GIF

Aug 20 2020

Estoy creando una red social y quiero saber si esta es una forma segura de subir fotos/gifs y videos.

if(isset($_POST['post'])) {

    $uploadOk = 1;
    $imageName = $_FILES['postToUpload']['name'];
    $errorMessage = "";
    $picdate = date('Y-m-d_H-i-s');

    if($imageName != "") {
        $targetDir = "assets/images/posts/";
        $imageName = $targetDir . uniqid() . basename($imageName);
        $imageFileType = pathinfo($imageName, PATHINFO_EXTENSION);
        
        if($_FILES['postToUpload']['size'] > 10971520) {
            $errorMessage = "Your file is to large";
            $uploadOk = 0;
        }

        if (strtolower($imageFileType) != "jpeg" && strtolower($imageFileType) != "png" &&
            strtolower($imageFileType) != "jpg" && strtolower($imageFileType) != "gif"
            && strtolower($imageFileType) != "mp4"&& strtolower($imageFileType) != "Ogg"
            && strtolower($imageFileType) != "WebM"){

            $errorMessage = "File type not allowed.";
            $uploadOk = 0;
        }

        if($uploadOk){
            if(move_uploaded_file($_FILES['postToUpload']['tmp_name'], $imageName)) {
                // image uploaded

            } else{
                // image did not upload
                $uploadOk = 0;
            }
        }
    }

    if($uploadOk) {

    $post = new Post($con, $userLoggedIn);

    $post->submitPost(trim(strip_tags(filter_var($_POST['post_text'], FILTER_SANITIZE_STRING))), 
        'none', $imageName);

    } else {

        echo "<div class='alert alert-danger'>
                $errorMessage
            </div>";
    }
}

Respuestas

2 Victor Sep 11 2020 at 20:56

Su código es inseguro porque:

  • Solo se basa en la extensión del archivo, por lo que los atacantes pueden cargar cualquier puerta trasera.
  • Accede a la variable $_FILES['postToUpload']['name']sin verificar si está definida y esto puede conducir a la divulgación de ruta completa.
  • Utiliza la función uniqid()sin ningún argumento, por lo que no se garantiza la unicidad y los archivos que se cargan simultáneamente y tienen el mismo nombre de archivo se sobrescribirán.
  • Almacena el nombre de archivo proporcionado por el usuario sin eliminar caracteres potencialmente peligrosos y esto puede generar resultados inesperados.

Algunas recomendaciones para mejorar tu código:

  • Deshazte de la $uploadOkvariable. Ya tiene y maneja la $errorMessagevariable y esto es suficiente para verificar si el archivo se cargó correctamente.
  • Debe definir $imageFileTypeen minúsculas, en lugar de llamar strtolower()para cada extensión.
  • Debe definir todas las extensiones de archivo aceptadas en minúsculas; de lo contrario, los usuarios no podrán cargar algunos archivos (en su caso WebMy Ogg, porque strtolower($imageFileType) != "Ogg"y strtolower($imageFileType) != "WebM"siempre será FALSE).