Similar function to imagecreatefrom for . doc/docx and pdf in PHP

Asked

Viewed 75 times

-1

I have been looking for something similar to the imagecreatefrom function, for different documents of images, like doc and pdf, but it seems that there is something of the kind. Currently I upload my files as follows:

$doc = $_FILES['arquivos'];
    $docs = $doc["name"];

    for ($i = 0; $i < count($docs); $i++) {
        $tiposPermitidos = array('image/gif', 'image/jpeg', 'image/pjpeg', 'image/png', 'doc', 'docx', 'pdf');
    $tamanhoPermitido = 1024 * 1024;
    $arqType = $doc['type'][$i];
    $arqSize = $doc['size'][$i];
    $arqError = $doc['error'][$i];
    if ($arqError == 0) {
        if (array_search($arqType, $tiposPermitidos) === false) {
            ?>
            <div class="fundo">O tipo de arquivo enviado é inválido! Arquivos permitidos: JPG, PNG, GIF, doc, docx, pdf</div>
        <?php } else if ($arqSize > $tamanhoPermitido) { ?>
            <div class="fundo">O tamanho do arquivo enviado é maior que o limite!</div>
            <?php
        } else {

            function create_ufilename($name, $path = '.') {
                $ext = pathinfo($name, PATHINFO_EXTENSION);
                $id = uniqid(rand(1, 100));
                $path .= '/' . $id . '.' . $ext;
                return is_file($path) ? create_ufilename($name, $path) : $path;
            }

            $img = $docs[$i];
            $diretorio = "../doc/";
            $tmp = $doc['tmp_name'][$i];
            $salvar = create_ufilename($img, $diretorio);
            $image = substr($salvar, 8);

            switch ($doc['type'][$i]):
                case 'image/jpeg':
                case 'image/pjpeg':

                    $largura = 500;
                    $altura = 300;

                    $imagem_temporaria = imagecreatefromjpeg($tmp);

                    $largura_original = imagesx($imagem_temporaria);

                    $altura_original = imagesy($imagem_temporaria);

                    $nova_largura = $largura ?? floor(($largura_original / $altura_original) * $altura);

                    $nova_altura = $altura ?? floor(($altura_original / $largura_original) * $largura);

                    $imagem_redimensionada = imagecreatetruecolor($nova_largura, $nova_altura);

                    imagecopyresampled($imagem_redimensionada, $imagem_temporaria, 0, 0, 0, 0, $nova_largura, $nova_altura, $largura_original, $altura_original);

                    imagejpeg($imagem_redimensionada, $diretorio . $image);

                    break;

                case 'image/png':
                case 'image/x-png':

                    $largura = 500;
                    $altura = 300;

                    $imagem_temporaria = imagecreatefrompng($tmp);

                    $largura_original = imagesx($imagem_temporaria);

                    $altura_original = imagesy($imagem_temporaria);

                    $nova_largura = $largura ?? floor(($largura_original / $altura_original) * $altura);

                    $nova_altura = $altura ?? floor(($altura_original / $largura_original) * $largura);

                    $imagem_redimensionada = imagecreatetruecolor($nova_largura, $nova_altura);

                    imagealphablending($imagem_redimensionada, false);

                    imagesavealpha($imagem_redimensionada, true);

                    imagecopyresampled($imagem_redimensionada, $imagem_temporaria, 0, 0, 0, 0, $nova_largura, $nova_altura, $largura_original, $altura_original);

                    imagepng($imagem_redimensionada, $diretorio . $image);

                    break;

                case 'image/gif':

                    $largura = 500;
                    $altura = 300;

                    $imagem_temporaria = imagecreatefromgif($tmp);

                    $largura_original = imagesx($imagem_temporaria);

                    $altura_original = imagesy($imagem_temporaria);

                    $nova_largura = $largura ?? floor(($largura_original / $altura_original) * $altura);

                    $nova_altura = $altura ?? floor(($altura_original / $largura_original) * $largura);

                    $imagem_redimensionada = imagecreatetruecolor($nova_largura, $nova_altura);

                    imagecopyresampled($imagem_redimensionada, $imagem_temporaria, 0, 0, 0, 0, $nova_largura, $nova_altura, $largura_original, $altura_original);

                    imagegif($imagem_redimensionada, $diretorio . $image);

                    break;

                default :
                    move_uploaded_file($doc['tmp_name'][$i], $diretorio . $image);

            endswitch;
        }

            $sql_doc = 'INSERT INTO doc (docs)';
            $sql_doc .= 'VALUES (:docs)';


            $query_doc = $conexao->prepare($sql_doc);
            $query_doc->bindValue(':docs', $image, PDO::PARAM_STR);
            $query_doc->execute();

        } else {
        ?>
        <p>Ocorreu algum problema ao enviar a imagem <?php echo $docs[$i]?>.</p>
        <?php
    }
   }

This "imagecreatefrom()" function creates a new image, wiping out some malware, if any, in the image, right? Is there any way to do something like this in other files than images for security reasons? After all, it is possible for the user to inject malware into a pdf, doc, etc... file and infect the server, right?

1 answer

1


In fact functions started in imagecreatefrom do not clean malware, at least none of this is specified in documentation.

As for security, if someone injects some malicious code into an image file or something, imagecreatefrom will return false because the image file will be badly formed. Even if you save the image or file using copy or move_uploaded_file unused imagecreatefrom in no time do you need to validate the file extension. You should lock only files with the extension. php and the like that can be run by PHP.

Once the file has an extension, when requested, the server will fetch the mime-type from it from its extension and try to respond accordingly. In this case image files do not execute PHP code.

Open a JPG file and at the beginning of the first line put it up on the apache server and try to access it through the URL. It will probably give some problem but will not show the 'Hello''.

  • Thanks Matheus, I have to study this part of security, I have a certain knowledge already, but it is not very thorough. Do you know of any place where I can delve deep into this theme other than the PHP documentation? I did study a little bit about pentest, but I didn’t go into it very much.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.