Jump to content

Segurança em sistemas de upload e download


laeknishendr

Recommended Posts

Já com um bom tempo sem escrever eu estava dando uma lida no exploit-db, vendo algumas novidades e resolvi escrever sobre uma coisa comum e simples, segurança em sistemas de download. Se você for parar para ver, é impressionante a quantidade de pessoas que criar sistemas de upload/download sem analisar os dados que estão entrando no servidor, e para complementar irei fazer uma citação cuja não lembro o autor, e não irei pesquisar no google agora ele, então isso fica ao seu critério – pesquisar ou não.

"Toda entrada de dados é maliciosa até que se prove o contrário."

A partir desse conceito que devemos partir para criarmos sistemas mais seguros, então isso quer dizer que devemos analisar todas entradas de dados, isso não quer dizer que você deve ler tudo que entra no site e avaliar se é seguro ou não, mas que você tenha noção do tipo de dado que está entrando e como isso pode afetar o sistema.

Sistema de download

Eu particularmente já encontrei várias brechas desse tipo em sites do governo, e em outros sites comuns ao longo da internet, o problema de muitos sistemas de download é que eles não verificam que arquivo está sendo baixado, apenas enviam o arquivo para você, o que permite que você baixe uma index, e vai baixando sources e lendo até chegar em um arquivo de configuração do banco de dados, e coisas do tipo. Irei simular um sistema que irá fazer uma verificação no arquivo que está sendo solicitado, e iremos permitir apenas algumas extensões, então, mão na massa.

<?php
/**
*
* @author Lucas A. Araújo <lucas.andrade@unimake.com.br>
* @link http://www.segbr.net
*
*/
class download
{
/**
 *
 * Extensões permitidas para download
 *
 * @var array
 *
 */
private $Extensoes = array();

/**
 *
 * Expressão regular construida a partir
 * das extensões que forem permitidas para download.
 *
 * @var string
 *
 */
private $RegExp;

/**
 *
 * Função responsável por verificar se o arquivo
 * que está sendo solicitado para download pode ser
 * baixado ou não.
 *
 * @param string $path
 * @return bool
 *
 */
public function ArquivoPermitido( $path )
{
 /**
	 *
	 * Define as extensões permitidas para download.
	 *
	 */
 $this->Extensoes = array("pdf", "jpg");

 /**
	 *
	 * Cria a expressão regular considerando as extensões
	 * que foram permitidas para download.
	 *
	 */
 foreach( $this->Extensoes as $Extensao )
	 $this->RegExp .= ".{$Extensao}|";

 /**
	 *
	 * Remove o ultimo caractere
	 *
	 */
	 $this->RegExp = substr($this->RegExp, 0, -1);

 /**
	 *
	 * Verifica se o arquivo solicitado para download está
	 * permitido com base na extensão.
	 *
	 */
 if( preg_match("/.{$this->RegExp}$/", $path ) )
 {
	 return true;
 }
 else
 {
	 return false;
 }
}
}

$Download = new download;

if( $Download->ArquivoPermitido( $_GET['path'] ) )
{
echo "Download permitido para: {$_GET['path']}";
}
else
{
echo "Download negado para: {$_GET['path']}";
}

?>

Para quem quiser testar no live: http://www.segbr.net/lucas/Download/?path=file.pdf

Eu ia fazer um outro trecho do texto para explicar sobre sistemas de upload de maneira mais específica, mas acho que será inutil, uma vez que empregada a analise do arquivo utilizando expressões regulares você poderá empregar isso no seu script de qualquer maneira.

Link to comment
Share on other sites

"Toda entrada de dados é maliciosa até que se prove o contrário."

http://www.segbr.net/lucas/Download/?path=file.txt%20dummy.pdf

==> Download permitido para: file.txt dummy.pdf

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Link to comment
Share on other sites

acho que um uso de uma classe para efetuar um código destes é desnecessário.

o mesmo se pode fazer muito mais simples desta forma

// lista de extensões permitidas
$exts = array(".pdf", ".jpg");
// verifica o nome do ficheiro para
// conter uma combinação de caracteres do grupo
//  - de 'a' a 'z'
//  - de 'A' a 'Z'
//  - o caracter '_'
//  - e o caracter '.'
// isto, seguido de um ".jpg" ou ".pdf" = (.jpg|.pdf)
if (preg_match('/[\.\w]*('.implode('|', $ext).')$/', $filename ) {
 // ok
} else {
 // não não
}

não foi testado, mas a solução rondará algo semelhante, sendo claramente mais "leve".

agora, se começares a enfiar mais métodos e regras, começa a fazer sentido juntar tudo, no entanto acho que uma simples função será necessário

IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.