Seções iMasters
Desenvolvimento + PHP

Desconfiar e Verificar

Quando trabalhando em um aplicativo web com colegas de trabalho ou com alguns voluntários, poucas coisas são mais importantes dentro do grupo do que
confiança. Confiança entre desenvolvedores permite que eles trabalhem confiantes,
facilita a comunicação entre os membros do time, e fortalece cada um deles para
que possam tomar boas decisões.

Com o aplicativo em si, no entanto, essa confiança nunca deve vir
facilmente, Com os aplicativos web de hoje, você não pode confiar em nada. Você
não pode confiar nos inputs do usuário, você não pode confiar no seu código,
você não pode confiar nos seus processos, e você não pode confiar nos seus
sistemas. Portanto, enquanto o provérbio russo diz, “???????, ?? ????????,” o
que significa “confie e verifique”, nos dias de hoje você precisa desconfiar e
verificar.

O usuário

Um usuário não
precisa de ser malicioso para violar o seu aplicativo, mas usuários maliciosos
existem, então nenhum input de nenhum usuário pode ser confiável. Qualquer dado
recebido é imediatamente suspeito, precisa ser validado se está no formato correto
(números são números, datas são datas, códigos postais são válidos, endereços
de e-mail devem corresponder à RFC 822, e os dados solicitados devem
estar com o comprimento correto) e filtrados para remover inputs perigosos.
Existem muitos artigos sobre como evitar a SQLinjection, mas prevenir ataques
do tipo cross-site
scripting e session hijacking também é importante.

Você deve desconfiar de dados entrando em seu aplicativo o suficiente
para ler os artigos na biblioteca do PHP Security Consortium, seguir um post por dia durante
um mês no PHP secutiry, ou passar uma hora revisando os básicos do PHP
Security.

Uma ótima fonte
(e que deve ser lida) para iniciantes – e que é cheia de ótimos lembretes para
desenvolvedores experientes – é o Essential PHP Security, que sucintamente lista
áreas problemáticas em que todos os desenvolvedores de PHP devem tomar cuidado,
juntamente com soluções.

Felizmente para
desenvolvedores que preferem usar frameworks, a maioria dos frameworks sabem
lidar com a checagem e com o filtro dos dados, prevenindo buracos bem
comuns na segurança. Se você usa um framework, abrace sua maneira de lidar com dados de
forma que não mine seus processos. Desconfie dele o suficiente para verificar
se ele faz o que você espera, e então se cadastre em sua mailing list de
segurança. Quando uma correção é reportada, faça o download do trecho e revise
as mudanças; você cometeu o mesmo erro no seu código?

O
código

O input de
usuários é somente uma parte do aplicativo; como você confia no seu código, se
ele parece brilhante às duas da manhã, mas talvez menos brilhante na manhã
seguinte? Você não confia. Você escreve unidades de testes.

Unidades de
testes permitem que você automatize o trabalho tedioso de verificar se o seu
código funciona corretamente e se está retornando os formatos de dados
corretos. Eles permitem que você saiba quando as mudanças afetam o resto do
sistema de maneira adversa.

SimpleTest e PHP Unit são dois frameworks PHP
de testes bem populares. A criação de unidades de teste tem sido feita de uma
maneira relativamente indolor, mas não sem erros e esforços.

Depois
que suas unidades de teste estão escritas, testando todas suas funções e
bibliotecas, será que você realmente pode confiar neles? Na verdade, não.
Unidades de teste são como o white box testing; você sabe o que o seu código
está fazendo (ou o que ele devia estar fazendo), você sabe qual input será
testado, e você sabe o que você espera em retorno. Com todo esse conhecimento,
não, você não pode nem confiar nas suas unidades de teste, pois todos os passos
são conhecidos, com a exceção dos inputs dos usuários.

Para
serem efetivas, as unidades de teste devem ser completas e devem ser
atualizadas para saberem lidar com novos casos que você vê durante o
desenvolvimento e em produção. Cada vez que um bug é descoberto, um problema desvendado,
ou uma proeza exposta, a unidade de teste deve ser criada para a questão.
Brainstorm em casos complicados; você talvez não coloque caracteres de controle
nos seus campos de formulários para inputs, mas as pessoas que cortam e colam,
ou que talvez usem Emacs, podem colocar. Para aplicativos multilíngues, você já
tentou fazer testes em outras linguagens?

Uma
revisão de suas unidades de teste de tempos em tempos também é uma boa idéia.
Já olhou para uma parte completa do seu projeto e achou isso?

/**
* Test validName function
* @param string input name
* @return boolean
*/
function testValidName($name) {
// TODO: write validName test
return true;
}

O
deployment

Então o input do usário é
desconfiado, checado e filtrado. O código é desconfiado, revisado e testado.
Você está pronto para lançar um novo atributo ou um programa completamente
novo. Agora é a hora de desconfiar dos seus processos de deployment, se eles
não estão documentados, repetitivos e (preferencialmente) não destrutivos.
Deployments manuais provavelmente vão gerar erros (“eu estava no passo 3 ou
4?”), com processos não documentados
sendo os piores deles (“O que você fez?” ”Eu não me lembro.”)

Documentar o lançamento de
um processo força você a pensar quais passos devem ser seguidos, quais
requisições devem ser feitas, e quais problemas você pode encontrar. Cada passo
tem pressupostos que devem ser questionados. As versões de desenvolvimento são
as mesmas para a produção em OS, web server, PHP e database? Algum passo tem
recursos limitados? O que acontece se um passo falhar? Você pode repetir um
passo sem se preocupar? O que poderia possivelmente dar errado aqui?

Existem passos que
necessitam de intervenção manual? Esses passos podem ser automatizados?
Automatizar um processo de deployment faz dele repetitivo e, neste ponto,
debugável. Phing, Capistrano (sim, você pode, use-o com PHP), shell scripts, seus
próprios scripts PHP, ou até Ant pode ser usado para construir uma
infraestrutura de deployment de acordo com as necessidades do seu projeto.

Quais checagens de erros
são necessárias nessa automação? Como você verifica que o deployment foi um
sucesso? Para web sites com uma única página, responder a “Ei, essa página
mostra alguma coisa?” é o suficiente. Para aplicativos maiores, você pode
executar testes contra ao vivo; faça o login na conta, execute uma série de
tarefas comuns, e verifique o resultado.

Ponto
de vista

Uma
vez que seu aplicativo é lançado, você pode respirar com alívio, e então
desconfie da sua visão do seu aplicativo. Você pode estar perto do seu
servidor, em uma conexão rápida, usando um browser com Javascript. Os seus
usuários podem estar do outro lado do mundo, com uma conexão ruim, e sem
JavaScript.

Você pode desconfiar da
sua visão fofa do seu aplicativo, e entender o que seus usuários estão
realmente vendo ao instalar o Charles ou qualquer outro proxy de debugging web.
Ao aumentar a latência da rede e deixar sua conexão lenta, você pode ver seu
aplicativo pelo ponto de vista de um usuário.

O
servidor

Seu
aplicativo pode ser sólido como uma rocha, perfeitamente seguro, e tremendamente
rápido, mas seu servidor pode se tornar o responsável pela travessura. É melhor
desconfiar disso também. A maioria dos provedores de hospedagem de hoje ainda oferecem
hospedagem compartilhada, com centenas de usuários em um único servidor. As
permissões erradas ou uma OS desatualizada podem comprometer algo que nenhum
dos seus códigos ou unidades de testes poderiam ter prevenido.

Portanto, ataque sua
aplicação como um usuário malicioso iria atacar. Use skipfish para atacar seu
aplicativo, e Nmap para escanear seu servidor.

Veja
quais portas você abriu, ou quais processos estão em execução. Descubra o que
você pode desativar para remover ameaças potenciais. Ter portas de acesso a
database abertas em um servidor sem limitações de IP, por exemplo, é uma
receita para o desastre.

Faça o download do
rainbow tables, e teste eles contra seu sistema. Tente instalar um
rootkit – tanto pela alegria de tentar penetrar em seu sistema, e porque,
realmente, a essa altura, você desconfia de tudo em seu servidor.

O
backup

É claro que, no final das
contas, a coisa mais fundamental em seu aplicativo são seus dados. Perdê-los
pode ser catastrófico para o projeto ou até para sua empresa. Nesse ponto, você
deve desconfiar dos seus backups.

A sua database está com backup, mas onde estão esses backups? Eles
estão na database do servidor? O que acontece se o hardware falhar? Existe
backup em outro servidor? O que acontece se o seu provedor de hosting fica fora
do ar? Você tem uma database master-slave no servidor preparada, de forma que
você sempre tenha um backup preparado? Quando foi a última vez que você
executou um SHOW SLAVE STATUS para determinar se o
slave está realmente replicando a data do master? Você tem um processo de
heartbeat em execução? Alguém está ouvindo às suas respostas? O monitoramento
do status da sua database só vai funcionar se alguém estiver prestando atenção.

A
principal questão, e o teste final de qualquer sistema de backup, é saber se
você reparou, com sucesso, seu sistema a partir de seus backups. As histórias
de horror sobre backups vazios são inúmeras, então repare a partir de um desses
backups, e inicie um staging server – mesmo que seja apenas em uma máquina
virtual. Repare a partir desse backup antes que você realmente precise dele.

Fundamentalmente, programar defensivamente, desconfiando das suas
suposições, e verificando cada parte do seu aplicativo, desde a menor linha de
código, até o último deployment, cria uma aplicação melhor e mais segura.

Existem muitas maneiras de
um projeto falhar; é melhor eliminar aquelas que você consegue.

Desconfie e verifique.

*

Texto original de Kitt
Hodsden, traduzido do inglês, disponível em

http://phpadvent.org/2010/mistrust-and-verify-by-kitt-hodsden.

 

Mensagem do anunciante:

Torne-se um Parceiro de Software Intel®. Filie-se ao Intel® Developer Zone. Intel®Developer Zone

Comente também

2 Comentários

Rafael Ribeiro

Que medo!!
Texto muito bom, fácil de ler.

Marcio

Velho! Muito bom este texto! Já comecei a repensar as formas de testar aplicações que estou utilizando…

Qual a sua opinião?