Proteger seu código PHP

Março 2017


Além de proteger o sistema operacional do servidor, o próprio servidor HTTP e as opções de configuração do PHP (php.ini), é importante garantir a segurança dos dados vindo dos usuários (através dos formulários ou dos URL, por exemplo), pois é normalmente daí que vêem a maior parte dos ataques da web.

Globalmente, estas medidas de prevenção podem ser classificadas em três grandes categorias:


Validar as entradas dos usuários


Quando o site apresenta formulários que permitem aos usuários digitar e enviar conteúdos, não basta indicar o formato dos dados a serem inseridos (endereço de e-mail, número de telefone, quantidade de produtos), também é preciso controlar o servidor (por exemplo, em PHP), se os dados estão de acordo com o esperado. Melhor. Quando se trata de números inteiros, basta converter os dados enviados pelo usuário na íntegra:

<?php $número_de_artigos = intval($_REQUEST['número_de_artigos']); ?>

Validar os dados transmitidos por URL ou por formulário


Em muitos casos, os dados transmitidos de uma página para outra são feitos através do URL (método GET) ou através de um formulário (método GET) ou (método POST) que o webmaster instalou. Assim, não é incomum que um URL se termine por um parâmetro indicando o item a ser exibido, como no exemplo a seguir:
/index.php?rub=25
.

Em princípio, os usuários não devem modificar esse parâmetro manualmente, mas não devemos esquecer que isso é possível. O que aconteceria se um usuário modificasse o URL de uma das seguintes maneiras:
/index.php?rub=0 


/index.php?rub= 
/index.php?rub=aaaaAAAAAaaaa 
/index.php?rub=1+or+1


Seja qual for o tipo de dados transmitidos por URL ou por formulário, é essencial verificar se o seu formato é o esperado!

Para isso, você pode usar a função filter_input().

Vejamos um exemplo com esta função. Um usuário te enviou um endereço de e-mail através de um formulário do tipo POST. O campo se chamava "e-mail". Para recuperá-lo você deve proceder da seguinte forma:

$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL); 
if($email){ 
    //O endereço de e-mail digitado possui um formato de endereço de e-mail 
}


Você pode filtrar um monte de coisas usando este recurso: endereços IP, URLs. Você também pode aplicar as alterações como, por exemplo, codificar uma cadeia prevista para passar em uma URL, como teria feito o htmlentities(). Vários filtros podem ser combinados se usarmos o operador bit a bit "|".

Exemplo para só validar um IP em um URL, se ele corresponder ao formato de um IPv4:
$ip = filter_input(INPUT_GET, 'ip', FILTER_VALIDATE_IP | FILTER_FLAG_IPV4);


Você encontrará todos os filtros utilizáveis neste endereço.

NOTA: Se você precisar aplicar um filtro diretamente a uma variável, você pode usar o filter_var().

Se livrar do conteúdo exibido ou transmitido por URL


Quando o conteúdo digitado pelo usuário é exibido na tela, é possível que ele contenha o código HTML ou o código JavaScript; é por isso que devemos proteger (o termo apropriado seria: livrar) o conteúdo do usuário:
Se o conteúdo é destinado a ser exibido em HTML: você deve "HTML encoder" o conteúdo antes de exibi-lo, ou seja, converter todos os caracteres especiais em entidades HTML equivalentes. PHP tem uma função para automatizar esse processo:
echo htmlentities($_REQUEST['conteúdo']);


Se o conteúdo é destinado a ser exibido em um URL: você deve "URLEncoder" o conteúdo antes de passá-lo como parâmetro para uma URL. PHP possui duas funções para fazer esta codificação: urlencode() e rawurlencode(). A diferença entre essas duas funções encontra-se na codificação de um espaço que,; no primeiro caso, dá 20% e "+", no segundo.
echo 'http://www.meusite?valor='.urlencode($_REQUEST['valor']);


Se o conteúdo deve ser armazenado em um banco de dados: é necessário livrar todos os caracteres com uma função específica no servidor do banco de dados utilizado. No caso do PHP e MySQL, a função mysql_escape_string() converte todos os caracteres potencialmente nocivos contidos na string passada como parâmetro.
$query = 'SELECT id FROM matable WHERE user="'.mysql_escape_string($_REQUEST['user']).'"';



Saiba que, se o servidor PHP for configurado com a opção magic_quotes, os dados transmitidos pelos usuários são automaticamente protegidos com barras invertidas. Portanto, antes de protegê-los com mysql_escape_string é preciso "desfazer" esta proteção básica:

$query = 'SELECT id FROM matable WHERE user="'.stripslashes(mysql_escape_string($_REQUEST['user'])).'"';

Veja também




Tradução feita por Lucia Maurity y Nouira

Veja também

Artigo original publicado por . Tradução feita por pintuda.
Este documento, intitulado 'Proteger seu código PHP', está disponível sob a licença Creative Commons. Você pode copiar e/ou modificar o conteúdo desta página com base nas condições estipuladas pela licença. Não se esqueça de creditar o CCM (br.ccm.net) ao utilizar este artigo.