Security issue when uploading

Asked

Viewed 546 times

2

I have an application built with Codeigniter that uploads image files to a directory on the server. Running on the localhost works perfectly. When on the official server, an error is returned when trying to transfer the file. Suspecting lack of permission in the folder, I asked the person who takes care of the server to free access to the directory. This person said there would be a security risk and asked me to find an alternative upload mode.

The question is: How to upload files without having to open all the server defenses? Below follows the view code.

HTML:

 <table width="100%" cellspacing="0" cellpadding="0" border="0" id="Table11">
   <tbody>
      <tr>
        <td>               
           <br />
           <div id="resposta" style="width: 120px; height: 60px; border: thin dashed #555;">

           </div>
           <br />
           <form name="formUpload" id="formUpload" method="post">
                <span class="label" id="Label14">Banner:</span>
                <label><input type="file" name="arquivo" id="arquivo" size="45" style="font-size: 11px; " /></label>
                 <br />
                 <progress value="0" max="100"></progress><span id="porcentagem">0%</span>
                 <br />
                 <input type = "button" value="Enviar Banner" onclick="enviarBanner()" style="margin: 5px; border: 1px solid #555; cursor: pointer; font-size: 12px;" />
              </form>
            </td>
         </tr>
     </tbody>
 </table>

Javascript:

 <script type="text/javascript">
 function enviarBanner(){
            if($.trim($('#descBanner').val()) === ""){
                alert("Campo Desciçao é Obrigatorio");
                $('#descBanner').focus();
                return;
            }
            arquiv = $('#arquivo').val();
            $('#formUpload').ajaxForm({     
                uploadProgress: function(event, position, total, percentComplete) {
                    $('progress').attr('value',percentComplete);
                    $('#porcentagem').html(percentComplete+'%');
                },  
                success: function(data) {
                    $('progress').attr('value','100');
                    $('#porcentagem').html('100%'); 
                    if(data.sucesso === true){
                        enviado = true;
                        $('#resposta').html('<img src="<?php echo base_url()?>'+ data.msg +'" width="120" height="60" />'); 
                    }
                    else{
                        $('#resposta').html(data.msg);
                    }                
                },
                error : function(){
                    $('#resposta').html('Erro ao enviar requisição!');
                },
                dataType: 'json',
                url: '<?php echo base_url()?>areaRestrita/banners/imgUpload',
                resetForm: true
            }).submit();
            enviado = true;
        }
</script>

Below follows the upload function:

function imgUpload(){

           $arquivo = $_FILES['arquivo'];

           $tipos = array('jpg', 'png', 'gif', 'psd', 'bmp');

           $enviar = $this->uploadFile($arquivo, 'Imagens/banners/', $tipos);

       }

function uploadFile($arquivo, $pasta, $tipos, $nome = null){
$nomeOriginal = "";
    if(isset($arquivo)){
        $infos = explode(".", $arquivo["name"]);
        if(!$nome){
            for($i = 0; $i < count($infos) - 1; $i++){
                $nomeOriginal = $nomeOriginal . $infos[$i] . ".";
            }
        }
        else{
            $nomeOriginal = $nome . ".";
        }
        $tipoArquivo = $infos[count($infos) - 1];
        $tipoPermitido = false;
        foreach($tipos as $tipo){
            if(strtolower($tipoArquivo) == strtolower($tipo)){
                $tipoPermitido = true;
            }
        }
        if(!$tipoPermitido){
            $retorno["erro"] = "Tipo não permitido";

        }
        else{
            if(move_uploaded_file($arquivo['tmp_name'], $pasta . $nomeOriginal . $tipoArquivo)){

                $retorno["caminho"] = $pasta . $nomeOriginal . $tipoArquivo;
            }
            else{

                $retorno["erro"] = "Erro ao fazer upload";

            }
        }
    }
    else{
        $retorno["erro"] = "Arquivo nao setado";

    }

    return $retorno;
}
  • Where is the code in which you use this function uploadFile?

  • The function imgUpload(), called in Javascript code does some checking and calls, in turn, the function uploadFile, which is displayed above.

  • 1

    Related question in the English OS http://stackoverflow.com/questions/256172/what-is-the-secure-method-for-uploading-a-file :)

  • In order to proceed with the precise upload of permissions... which server is it that does not allow and still sends to look for alternative? rsrsrs An alternative is to send the files via FTP using the ftp functions of php, another alternative is to switch server.

  • The permission "problem" is more connected with the way the server was configured. Your user must be in the same user group as the one running Apache (or another web server). Thus, it is possible to use 775 permission instead of 777.

  • The server administrator is right. You will include a serious security risk. The suggested pattern for these cases is to record the image in a database, such as Mysql or SQL Server.

Show 1 more comment

1 answer

-2

Good afternoon, this question is quite relative, but what can be done is the following: give permission to "write" to the owners of the directory (whether it may be you) where will only contain the images (this you see with the people who take care of the server) and also add a file ". htaccess" not to let you access the root folder (type showing the name of all files in the browser).

It is common to have a directory only for images and not therefore need to break the server security.

Security tip: Save your images with encrypted names on the server (in the database you can save the original name along with the file encryption) and when pulling the images from this directory, watch out for attacks from "Cross Directory"that in place of the image would be more or less that:

https://seusite.com.br?imagem=../.. /.. /.. /.. /etc/passwd

Browser other questions tagged

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