Requisito 4: Sem erros para o usuário
Falaremos aqui de outro ponto importantíssimo na questão de segurança que é freqüentemente ignorado pelos desenvolvedores: as mensagens de erro.
As mensagens de erro foram feitas para que o desenvolvedor possa trabalhar de forma mais prática e descobrir o que ele está fazendo de errado. Observem, entretando, que, quando uma aplicação atinge maturidade suficiente para "entrar em produção", torna-se imperativo que o usuário não visualize mensagens de erro.
A razão disso é muito simples: as mensagens de erro freqüentemente trazem informações sensíveis. Observe como exemplo uma típica mensagem de falha de conexão com a base de dados:
Warning: mysql_connect() [function.mysql-connect]:
Access denied for user 'foo'@'localhost' (using password: YES)
in /usr/local/apache/htdocs/script.php on line 2
Note, através das partes destacadas, que esta mensagem me informa:
- O tipo de RDBMS: mysql
- O usuário de conexão com a base: foo
- Que este usuário está tentando uma conexão de dentro do servidor: localhost
- O caminho absoluto da raiz web: /usr/local/apache/htdocs
- O nome do script: script.php
É por isso que, quando colocamos uma aplicação em produção, ocultamos as mensagens de erro e as gravamos diretamente em um arquivo de log. Isto é muito simples de implementar:
Exemplo:
display_errors = Off
log_errors = On
error_log = /log/php_errors.log
Requisito #5: Esconda do servidor web o que ele não precisa acessar
Quantos de nós não usamos em nossas aplicações um arquivo, tipicamente chamado de config.php ou setup.php, onde guardamos, por exemplo, usuário e senha da base de dados?
Não há nada de errado nisso, mas cuidado: se este arquivo não gera saída de informação em HTML, por que deixá-lo acessível via web?
Para esclarecermos o problema, vamos definir 3 coisas:
- minha raiz web é: /usr/local/apache/htdocs
- meu arquivo de configuração fica localizado em /usr/local/htdocs/config/config.php
- este é um código típico que usa este arquivo:
require_once("/urs/local/htdocs/config/config.php");
/ bla bla bla /
Observe que o erro neste caso é confundir interpretador PHP e servidor web. O Apache (ou IIS, Xitami etc) não precisa saber onde está este arquivo. Isto é responsabilidade do interpretador.
Outro problema é que se arquivo fica desnecessariamente exposto, afinal de contas basta eu abrir um navegador e digitar:
http://www.meusite.com.br/config/config.php
Não faz sentido. Por mais que você possa argumentar que não há forma de ler o código-fonte deste arquivo, ainda assim, isto não muda o fato de que ele está desnecessariamente exposto.
A solução é simples: movemos o arquivo para fora da raiz web:
/usr/local/config/config.php
E depois apenas acertamos as permissões e corrigimos nosso código:
require_once("/urs/local/config/config.php");
/ bla bla bla /
A partir de agora nosso arquivo de configuração só pode ser lido por quem precisa dele: o interpretador PHP.
Requisito #6: Use criptografia
Dados sigilosos são chamados assim por um motivo. Quando tratamos especificamente de senhas é impressionante a quantidade de aplicações web que gravam senhas em texto puro na base de dados.
Ora, se a senha possui a importância que tem e quem a escolhe é o usuário, por que alguém mais precisa ler essa senha?
Se a senha possui este peso em nossa aplicação, não podemos nos dar o luxo de fazer com que ela trafegue pela aplicação totalmente exposta.
PHP implementa criptografia de várias formas, mas eu sugiro - para quem puder usar, pois exige instalação e configuração extra - a utilização da função mcrypt
.
Os hashes MD5 e SHA-1 são opções válidas, mas o problema é a sua fragilidade: para o MD5 existe até dicionário de dados, enquanto o SHA-1 foi recentemente "quebrado" por um pesquisador chinês.
Conclusão
A implementação de regras básicas de segurança depende apena da boa vontade do desenvolvedor. Você deve ter percebido como a maior parte das soluções aqui apresentadas significam simples mudanças de hábito.
É mais do que tempo de nós, desenvolvedores PHP, deixarmos de lado nossos antigos vícios e começarmos a implementar boas práticas de programação.
Ganha o profissional, ganha a sua aplicação, ganha o seu cliente, ganha o mercado. Só quem perde nessa situação é quem tenta se aproveitar de nossa aplicação.
Referências e links sugeridos
[PHP Security Consortium] - http://phpsec.org/
Er Galvão Abbott trabalha há mais de dez anos com programação de websites e sistemas corporativos com interface web. Autodidata, teve seu primeiro contato com a linguagem HTML em 1995, quando a internet estreava no Brasil. Atualmente, além de lecionar em diversos cursos, tem se dedicado ao desenvolvimento de sistemas baseados na web, tendo nas linguagens PHP, Perl e JavaScript suas principais paixões.
Parte I