Perigos da validação client-side (ou Sempre valide client E server side)

14 F Y

Desenvolvo para a web há praticamente 8 anos. Pude ver muita coisa surgindo, tecnologias, conceitos, frameworks, aplicações, serviços… O bom de aprender cedo a desenvolver é que você presta atenção as falhas dos outros para não comete-las em seus projetos. Já vi absurdos completos, como um site em que os dados do login eram enviados via GET, usuário e SENHA, plaintext, na url de destino… Outros erros comuns, que por vezes me deparo são mais mascarados, mas qualquer desenvolvedor com o mínimo de experiência os conhece e deve tentar evitá-los. Um exemplo é SQL Injection… a técnica é conhecida desde sempre, no entanto, grandes portais ainda são vulneráveis a este “ataque” trivial, que qualquer usuário pode realizar. Já vi o site de um jornal importante, de grande circulação, abrindo as pernas para um “‘or 1 = 1’ ” colocados como usuário e senha… Mas o foco deste post não é este tipo de problema. Quero discutir aqui sobre outra fragilidade de aplicações web, ainda mais fácil de tratar do que SQL Injections ou XSS: Confiar na validação client-side.

Muita gente que desenvolve aplicações web atualmente, vem do mundo da programação desktop normal. Ao validar um campo (um textbox por exemplo), basta validar o valor inserido pelo usuário e processar aquele valor normalmente (se for o caso de inserção em banco de dados, vale a pena colocar validação no banco também, tanto para desktop como principalmente para web). Se quiser desabilitar algum campo, apenas desabilite ele na interface gráfica e pronto, o usuário não vai ter acesso à ele (não na prática, com facilidade suficiente). Ao desenvolver para web, assumir isto pode ser fatal para sua aplicação.

Modificar o conteúdo exibido em uma página, ou mesmo alterar os valores enviados via POST são atividades triviais, que um usuário com conhecimentos mínimos de HTML e/ou do protocolo HTTP podem fazer, usando complementos para o Firefox como o Firebug e o TamperData.

Através do Firebug, é muito fácil alterar por exemplo, o valor de um <option>, para enviar o valor que o usuário desejar, ao invés dos valores pré-definidos. Remover um “disabled” de um input checkbox ou radiobutton é trivial. Com a mesma facilidade, podem ser removidas as chamadas às funções javascript que realizam validação client-side. Confiar em validações feitas em javascript já não é algo muito inteligente, pois praticamente qualquer browser tem opções fáceis de desabilitar a execução de tais scripts.

A validação client-side no entanto não deve ser esquecida. Para o usuário honesto, sem intenção de quebrar o sistema ou explorar vulnerabilidades, ela é muito útil, diminuindo o tempo de resposta caso algum dado esteja incorreto (evitando que os dados sejam enviados, processados pelo servidor, verificados como incorretos e só então ser enviada uma mensagem de erro para o cliente corrigir os dados não conformes), melhorando assim a experiência do usuário.

Frameworks como ASP.NET oferecem facilidades para o desenvolvedor no momento de validar tanto client como server side. Os componentes de validação realizam uma validação client-side, no entanto, todas as verificações são novamente realizadas no momento em que os dados chegam no servidor. Caso estes não sejam válidos, Page.IsValid irá retornar false, e cabe ao desenvolvedor realizar uma verificação ao valor desta propriedade antes de usar os dados. No entanto, deve-se escolher corretamente as validações a serem realizadas em cada cenário, caso contrário, ainda assim poderão passar dados que não deveriam.

Se você acredita que isto é muito teórico, não acontece na prática, está enganado. Nestes dias, um amigo meu foi se inscrever em um curso. Eu e outro amigo já haviamos conseguido nos inscrever, mas as inscrições eram gratuitas, e as vagas haviam se esgotado quando este outro amigo tentou. Quando analisamos a página (escrita em ASP puro, não ASP.NET), percebemos que o radiobutton para escolher o curso que ele desejava estava com um disabled. Resolvemos alterar via Firebug (apenas remover o atributo disabled=”disabled” da tag), selecionar o curso e enviar o formulário. Resultado: Inscrição realizada com sucesso, e quando ele foi ao curso, estava o nome dele lá na lista de inscritos… Até certificado ele recebeu, tudo normal.

Num caso destes, teria que ser verificado se ainda existiam vagas no momento em que o servidor recebe a solicitação. Não precisaria nem de Firebug para um sistema que apenas valida client-side receber mais candidatos inscritos do que deveria. Uma página guardada em cache visitada antes do fim das vagas poderia inscrever várias pessoas. Outro cenário possível era se existisse apenas uma vaga aberta, mas 5 usuários tivessem carregado a página de inscrição ainda com esta vaga restante. Todos eles conseguiriam se cadastrar pela falta de uma validação server-side.

Neste caso, o efeito foi inofensivo. Não faltou lugar, comida (ótimo coffee-break por sinal 🙂 ) nem nenhum outro recurso necessário ao bom andamento do curso por causa desta inscrição adicional. No entanto, cenários em que o dano causado pela falta de verificações semelhantes podem ser consideráveis não são difíceis de imaginar.

Fica o recado, SEMPRE valide seus dados server-side para evitar problemas! Apesar do “trabalho” adicional (que varia consideravelmente dependendo da tecnologia que você estiver usando), vale a pena para garantir o comportamento que você ou seu cliente esperam do seu sistema.


Visual SVN Server – Um servidor subversion “plug and play” e free

4 F Y

Todos sabem, ou deveriam saber, a importância de manter um projeto sob alguma forma de controle de versão, principalmente quando este projeto vai ser realizado por vários integrantes, que podem estar programando sem estar em contato uns com os outros, em arquivos diferentes ou às vezes um mudando os arquivos dos outros. As vantagens de integrar os códigos dos diferentes membros do projeto durante todo o andamento das atividades, de possuir um log com todas as alterações que foram feitas, possuir os códigos de cada versão, podendo reverter um dado arquivo para uma versão mais antiga que funcionava e até mesmo a possibilidade de verificar a atividade de cada participante do projeto são apenas alguns dos motivos para alguém usar uma ferramenta de controle de versão.

Desde projetos pequenos, como alguns da universidade, que vão durar um mês e ter no máximo 4 ou 5 participantes, até grandes projetos como os hospedados no sourceforge (eMule por exemplo), é interessante possuir uma ferramenta de versionamento. Existem vários sites que oferecem o serviço gratuitamente, alguns exigindo que o projeto seja open-source, como o Google Code (http://code.google.com/hosting/), no qual você deve escolher entre algumas licenças como GPLv2 ou 3, Apache ou Mozilla e possui um espaço limitado (se não me engano são 100MB) para manter seu código. Outros sites como o Assembla (http://www.assembla.com, oferece 500MB) permitem projetos fechados (EDIT: Desde outubro de 2008 o Assembla deixou de oferecer o serviço gratuito para projetos de código fechado. Projetos opensource continuam podendo ser hospedados por lá sem problemas). Já tive a oportunidade de trabalhar com ambas as ferramentas citadas acima, e posso dizer que elas foram muito úteis para projetos da universidade e outros projetos pessoais. Quando os projetos passam a ser fechados, envolver dinheiro realmente, em que o código deve ser protegido e/ou não se pode depender totalmente da conexão com a internet, usar uma ferramenta na web pode não ser a melhor opção (mesmo que alguns dos serviços, como o Assembla, ofereçam versões pagas que resolvem alguns dos problemas de ter seu repositório todo na web). Daí surge a necessidade de instalar seu próprio servidor SVN ou CVS, e com isso, pode surgir uma grande dor de cabeça.

Resumindo bem, a maioria dos servidores “oficiais” de controle de versão são realmente complicados pra instalar. Já vi gente que já tinha instalado umas dez vezes um servidor de CVS se passar pra conseguir instalar a décima primeira vez… O processo as vezes parece até místico :p. É instalação deszipando arquivo, escrevendo comando em prompt, alterando variável de ambiente do SO… enfim, seu projeto pode correr o sério risco de parar antes de ter uma linha de código escrita. Os leitores mais masoquistas podem dar uma olhada neste site, que possui um passo-a-passo de como instalar o servidor subversion normal e criar um repositório. Pra simplificar tudo isto, vou falar sobre o VisualSVN Server.

Como citei no título deste post, o VisualSVN Server é grátis, pra qualquer tipo de projeto, ao contrário do cliente VisualSVN para o Visual Studio, do qual falei neste outro post. Também falei que o VisualSVN Server é “plug an play”… estou tomando esta expressão emprestada do pessoal de hardware, pois é a melhor expressão que eu encontro para falar sobre este programa. A única ação que você precisa tomar para criar o servidor é instalar o programa. Pronto, não precisa mais enfiar valores bizarros nas variáveis de sistema nem se embrenhar em prompts cinza-sobre-preto (particularmente, prefiro verde-sobre-preto). Toda a manutenção é feita através do console de gerenciamento do sistema, aquele mesmo que é usado para gerenciar o IIS ou os discos no seu Windows, através de uma interface extremamente limpa e fácil de usar. A criação de um repositório, de usuários e a atribuição de quais usuários vão ter acesso (e em que nível) a cada repositório é extremamente simples. Para exemplificar bem como este processo é simples, vou mostrar um passo-a-passo, ilustrando com screenshots das telas, sobre como criar seu repositório usando o VisualSVN Server.

1. Baixe o VisualSVN Server. Vá em http://www.visualsvn.com/server/ e baixe a versão mais nova do programa. Este é o único arquivo que você precisará baixar para fazer seu servidor funcionar.

2. Rode o Instaladador. A Tela de Instalação mais importante é a seguinte:

VisualSVN Server - Instalação

Nela você escolhe onde o programa será instalado, em que pasta ele irá manter os repositórios (note que para escolher, você deve clicar no respectivo botão Browse), o nome do servidor, uma porta para o servidor (a porta padrão é 8443) e se você quer ou não usar https. Eu gosto de usar https e mudar a porta pra qualquer outra, mas isso fica a seu critério.

3. Depois de concluir a instalação, seu servidor de repositórios já está rodando! Se quiser conferir, vá em http(ou https)://NomeDoSeuServidor:SuaPorta . Você ainda não criou nenhum repositório nem nenhum usuário, então não vai conseguir ver nada. Vamos criar agora.

4. Abra o console de configuração do VisualSVN Server. Você deve ver uma tela como a seguinte:

VisualSVN Server - Manager1

Vamos primeiro criar um usuário. É só ir com o botão direito em Users, e clicar em “Create User”. Informe um login, digite e confirme a senha (a senha é case-sensitive) e crie o usuário. Se você tentar agora entrar na página do seu servidor e passar este usuário/senha, você vai ter uma tela como a seguinte:

VisualSVN Server - Repositories1

Para alterar a senha ou remover um usuário, basta clicar sobre o login desejado na tela de usuários e escolher a ação.

5. Agora vamos criar um repositório. Também é uma operação extremamente simples, basta clicar com o botão direito em “Repositories”, “Create Repository…” e escolher um nome para ele. Na tela onde você bota o nome para seu repositório, você tem a opção de escolher se devem ser criadas as pastas padrão de um projeto no svn: “trunk”, usada para manter os arquivos em desenvolvimento, “branches” para as versões suficientemente estáveis, onde não haverá mais desenvolvimento, apenas correções, e posteriormente o código sofrerá testes exaustivos, e “tags”, que são realmente as versões de release do projeto. Recomendo fortemente deixar o servidor criar estas pastas, dado que são um padrão quando se usa o SVN.

6. Finalmente, você deve configurar quem terá acesso ao seu repositório. Clique com o botão direito sobre o nome de seu repositório e escolha “security”. Por default todos tem acesso de leitura e escrita, para mudar isto basta você remover o grupo “Everyone” da lista e adicionar os usuários que você deseja que tenham acesso e qual nível de acesso você deseja dar para cada usuário ou grupo.

7. Tudo pronto, agora basta você dar um checkout usando o cliente svn de sua preferência para o endereco [[http ou https)]]://[[NomeDoServidor]]:[[PortaDoServidor]]/svn/[[NomeDoRepositorio]]/

Pronto, seu repositório está criado e você pode fazer o que quiser com ele :)… Bem simples, e em 5 minutos você tem um servidor de controle de versão para seu projeto rodando! Qualquer dúvida, pode postar um comentário que eu tento responder o mais rápido que der.