você está aqui: Home  → Arquivo de Mensagens

Salvando a pele do Programador php - Uploads de arquivos indevidos

Colaboração: Altemir Braz Dantas Junior

Data de Publicação: 03 de março de 2011

Seguindo a mesma linha da dica Salvando a pele do Programador php - SQL Injection.

Então vamos lá. Primeiramente crie um arquivo php contendo as seguintes linhas:

ex: security.php

  /*
    aqui vai varrer todos FILES (variavel responsavel por arquivos) e jogar
    o o nome do arquivo para a funcao verifica_extensao
  */
  
  foreach ($_FILES as $f){
     foreach($f as $index=>$valor){
         if($index == 'name'){
             verifica_extensao($valor);
         }
     }
  }
  
  function verifica_extensao($var){
  
  //aqui um array de todas as extensoes proibidas para upload
     $proibidas['extensoes'] = array('php', 'phps', 'exe','bat','msi','asp','js');
  //pega a extensao em minusculo
     $extensao               = strtolower(end(explode('.',$var)));
     $existe                 = in_array($extensao, $proibidas['extensoes']);
  
     if ($existe) {
         echo "< script>alert('Erro: Extensão Proibida!');history.go(-1);</script>";
         exit;
     }
  }

Agora é só dar um include desse arquivo na lib principal ou em todos os arquivos php que fazem upload.



 

 

Veja a relação completa dos artigos de Altemir Braz Dantas Junior

Opinião dos Leitores

Gustavo
04 Mar 2011, 12:47
Em termos de segurança é leviano dizer que algo "é totalmente falho". Na segurança, tudo se adiciona!

Tudo depende do servidor onde estiver rodando e de como é configurado e dependendo de como o site é programado, tudo pode virar uma falha.

O apache reconhe os arquivos com scripts pela extensao e não pelo content-type, e os executáveis devem se restringir à área cgi-bin.

E ainda, um script php ou qualquer outra linguagem pode estar em um arquivo de content-type text/plain. Ou ainda, podemos maquiar um script dentro de um arquivo com extensão qualquer e content-type mascarado também.. se o usuário é avançado, tudo é mascarável.

Aliás, já vi casos em que é feito o upload de arquivos de imagem do tipo 'foto.gif.php' onde os primeiros bytes do arquivo são "GIFxx;<?php ... ?> ", justamente pra conseguir acesso a servidores que só verificam o content-type e não verificam a extensão do arquivo

Mais informação em:

http://www.phpclasses.org/blog/post/67-PHP-security-exploit-with-GIF-images.html

http://birdhouse.org/blog/2007/06/19/php-inside-image-files/




Thiago Paes
04 Mar 2011, 09:49
Na verdade, filtrar pela extensão é totalmente falho, visto que não estamos nos protegendo de usuários normais, e sim mais avançados, que obviamente, sabem trocar a extensão de um arquivo.

O mais correto na minha opinião, seria filtrar via content-type, pegando o mesmo via mime_content_type (depreciada já) ou utilizando a extensão PECL Fileinfo (http://www.php.net/manual/en/ref.fileinfo.php).
Gustavo
03 Mar 2011, 12:43
Bem lembrado, muito importante uma vez que a maioria dos programadores acaba dando permissão 0777 para os arquivos.
Rudinei Dias
03 Mar 2011, 11:28
A lista de PERMITIDOS, impedindo o upload de todos os demais, acrescenta mais segurança, pois impediria, no caso do artigo, o upload de um arquivo .sh ou sem extensão que, no caso dos *nix, pode ser executado.
Gustavo
03 Mar 2011, 02:31
faltou dizer... não podemos esquecer que para cada hospedagem, pode estar habilitadas também outras linguagens como perl, ruby, python, ..., o que torna impraticável prever todas as extensões que devem ser bloqueadas.
Gustavo
03 Mar 2011, 02:29
Na realidade, é mais recomendável fazer uma lista das extensões que são permitidas em cada ocasião, ou ainda, criar um ID para o nome do arquivo e guardar o nome original em um banco.

Por exemplo: o arquivo "infectado.php" seria salvo no sistema de arquivos como 123456 e o nome registro em uma tabela no banco de dados. O que permitiria manter o nome original para o arquivo, e salva-lo no servidor sem risco de servir a propósitos indesejados.

Na hora de fazer o download, usar os headers apropriados para retornar o nome original ao arquivo:

header('Content-Disposition: attachment; filename="infectado.php"');

echo file_get_contents('123456');
*Nome:
Email:
Me notifique sobre novos comentários nessa página
Oculte meu email
*Texto:
 
  Para publicar seu comentário, digite o código contido na imagem acima
 


Powered by Scriptsmill Comments Script