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.

Anúncios

OpenDNS – Resolvendo problemas com o servidor DNS do seu provedor

9 F Y

A Lei de Murphy é implacável… quando você mais precisa enviar aquele email importante, do nada, seu GMail não abre. Você tenta abrir google, globo.com, uol, qualquer coisa que está SEMPRE no ar, mas nada abre. Teoricamente, “a internet caiu”. Com meu Giro da Embratel, isso acontecia direto, principalmente durante a semana em horário comercial. A questão é que, se você tentar abrir algum daqueles sites pelo seu endereço IP, ele abre. E agora, qual é o problema?

A resposta para isso é o servidor DNS do seu provedor. Resumindo, este servidor converte o endereço que você conhece (que é um “apelido”), como http://www.google.com, para um número como 64.233.169.103, que é o endereço IP, o endereço “real”, pelo qual o seu computador vai conseguir entrar em contato com o google na prática (o buraco é bem mais embaixo do que isso que eu tou falando, mas não tem pra que complicar aqui. Este link leva para uma página explicando melhor o que é e como funciona DNS).

Servidores DNS mal configurados ou dimensionados podem causar sérios problemas, pois ninguém é obrigado a decorar IPs (pra isso o DNS foi criado). Infelizmente, vários provedores não oferecem servidores DNS de qualidade, o que dificulta a experiência do usuário, e muitas vezes impossibilita a navegação (novamente, usuários do Giro que o digam…).

Para resolver problemas de performance, segurança, diponibilidade e por fim melhorar a experiência do usuário, em 2005 foi lançado um serviço chamado OpenDNS. Eles oferecem um endereço IP que você irá colocar como seu servidor DNS, passando por cima do servidor de seu provedor. Quando uma requisição for feita para este “servidor”, ela será realizada na verdade por algum dos diversos servidores da rede do OpenDNS. Por possuirem vários servidores, é garantido que haverá uma resposta para a sua requisição. Apesar destes servidores estarem localizados nos EUA e na Europa, a qualidade do serviço oferecido em relação aos servidores toscos oferecidos por alguns provedores faz com que o tempo de resposta do OpenDNS seja melhor mesmo em relação à maquinas aqui no Brasil mesmo.

O melhor de tudo é o custo…  0800,  grátis, Zero. É só configurar a conexão para usar o OpenDNS e pronto. Estou usando na minha conexão do Giro, e estou conseguindo usar durante a semana em horário comercial tranquilamente, o que não vinha acontecendo há algum tempo. Em outros blogs, vi que tem gente usando ele também em conexões Velox e diminuiu a quantidade de problemas, tanto de disponibilidade como de performance.

Para configurar, siga estes links (em inglês, com as imagens das telas, bem intuitivo):

Para usuários de “discadas” em geral, ao invés de (no caso do XP) escolher “Local Area Network”, no passo 3 escolha a sua conexão.