Artigo Clube Delphi 85 - Validação por imagem na Web

Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Para efetuar o download você precisa estar logado. Clique aqui para efetuar o login
Confirmar voto
0
 (0)  (0)

Esse artigo faz parte da revista Clube Delphi Edição 85. Clique aqui para ler todos os artigos desta edição

Boa Idéia

Validação por imagem na Web

 

É cada dia mais comum o uso de imagens de validação em Web Sites. Mais que um quesito de segurança, é um artefato altamente recomendável para o controle de sua aplicação. Este artigo traz uma implementação desse tipo de validação, além de algumas sugestões para incrementar a segurança de aplicações com Delphi e ASP.NET, usando esse recurso.

 

Por que usar imagens de validação?

Atualmente, a maioria dos bits que trafegam na Internet, carregam conteúdos como spam, mídias ilegais, além de robots, que são aplicações que simulam requisições no servidor, ou seja, é como se alguém clicasse no botão Submit da sua aplicação.

Em virtude dessas ocorrências, cada vez mais é necessária a implementação de controles para incrementar a segurança dos sistemas usados na Internet. Abordaremos neste artigo, como criar uma interface que solicite a digitação de um código de verificação que foi gerado através de uma imagem. Imagine um site de votação para um concurso (Figura 1).

 

 

Figura 1. Formulário de cadastro de exemplo

 

Para não “cansar o braço” votando, um usuário, cria um robot que acessa a URL destino do formulário (action), enviando o código do seu candidato favorito (como, por exemplo, o link http://www.website.com.br/vote.aspx?idCandidato=10), que pode ser obtido através de uma simples consulta no código-fonte do browser.

Sendo assim, ele poderá fazer com que seu candidato ganhe o concurso, burlando a votação, pois o robot poderá ficar 24h por dia votando sem parar, em múltiplas instâncias de execução simultânea, inclusive. Esse é apenas um dos casos em que robots podem ser prejudiciais em aplicações Web.

 

Usando validação por imagem

Uma das implementações de segurança é o uso de imagens de validação em formulários Web, pois no momento da escolha do candidato favorito, o usuário deverá digitar o código impresso na imagem, que será validado no servidor para confirmar o voto.

O uso bem planejado dessas imagens pode evitar o acesso dos robots em sua aplicação. As imagens de validação possuem um conteúdo, geralmente formado por caracteres aleatórios ou expressões, que devem ser digitados manualmente em uma caixa de texto, para validar o envio de informações no submit de um formulário.

Ao contrário de expressões em texto puro, que são embutidas no HTML e poderiam ser facilmente descobertas por um robot, o texto de uma imagem só é perceptível ao olho humano. Ou pelo menos deveria.

Entretanto, gerar essa imagem não é o suficiente. São conhecidas as técnicas que conseguem rastrear o conteúdo de uma imagem e obter o texto digitado (técnica conhecida muitas vezes como OCR). Por esse motivo, é necessário gerar uma imagem com atributos que “atrapalhem” o rastreamento do conteúdo.

A sugestão de implementação que veremos certamente poderá ser incrementada com o uso da criatividade do desenvolvedor, para criar um conteúdo que possa ser reconhecido pela visão, mas não por algum algoritmo de rastreamento de imagem.

A imagem que criaremos será gerada por uma aplicação ASP.NET, com Response do tipo image/jpeg. Em outras palavras, teremos um documento ASPX, cujo conteúdo será a própria imagem. Agora que já vimos os fundamentos, vamos à prática.

 

Gerando a imagem

Abra o Delphi 8, 2005 ou 2006 e crie uma aplicação ASP.NET, dando o nome de “ImageValidating” para o projeto e clique em OK (Figura 2).

 

Figura 2. Criando o projeto ASP.NET

 

Adicione um novo arquivo ASPX (New Items>New ASP.NET Files>ASP.NET Page) e dê o nome de “image.aspx”. Começaremos a implementação do código pelo método que definirá o conteúdo da imagem, ou seja, o texto que deverá ser validado através da digitação no TextBox. Adicione o GenerateString (daremos esse nome ao método), conforme a Listagem 1.

 

Listagem 1. Método GenerateString

function TWebForm2.GenerateString: string;

var

  rnd: System.Random;

  validatingText: string;

  i: integer;

  chr: Char;

begin

  validatingText := '';

  for i := 0 to 6 do

  begin

    chr := Convert.ToChar(rnd.Next(65, 90));

    validatingText := validatingText + chr.ToString;

  end;

  Result := validatingText.ToUpper;

end;

 

O código da listagem anterior gera uma string com sete caracteres randômicos (nesse caso letras maiúsculas), que irão compor a validação. Essa string será inserida em um Session que será invocado posteriormente para a validação. No Page_Load da página adicione o código da Listagem 2.

 

Listagem 2. Page_Load da página

uses System.Drawing.Imaging,

  System.Drawing.Text, System.IO;

...

var

  x, y: integer;

  strValidation: string;

  rnd: System.Random;

  font: System.Drawing.Font;

  bitmap: System.Drawing.Bitmap;

  gr: System.Drawing.Graphics;

  Retangule: System.Drawing.Rectangle;

  Pen: System.Drawing.Pen;

  Point: System.Drawing.Point;

begin

  strValidation := '';

  rnd := System.Random.Create;;

 

  Response.ContentType := 'image/jpeg';

  Response.Clear();

  Response.BufferOutput := True;

 

  strValidation := GenerateString;

  Session['strValidation'] := strValidation;

 

  font := System.Drawing.Font.Create('Arial',

    rnd.Next(17,20));

 

  bitmap := System.Drawing.Bitmap.Create(200, 50);

  gr := Graphics.FromImage(bitmap);

 

  Pen := System.Drawing.Pen.Create(Color.White);

  gr.FillRectangle(Brushes.BlueViolet,

    Rectangle.Create(0, 0, bitmap.Width,

    bitmap.Height));

  gr.DrawString(strValidation, font, Brushes.White,

    rnd.Next(70), rnd.Next(20));

  gr.DrawLine(Pen, Point.Create(0, rnd.Next(50)),

    Point.Create(200, rnd.Next(50)));

  gr.DrawLine(Pen, Point.Create(0, rnd.Next(50)),

    Point.Create(200, rnd.Next(50)));

  gr.DrawLine(Pen, Point.Create(0, rnd.Next(50)),

    Point.Create(200, rnd.Next(50)));

 

  for x := 0 to bitmap.Width - 1 do

    for y := 0 to bitmap.Height - 1  do

      if (rnd.Next(4) = 1) then

        bitmap.SetPixel(x, y, Color.White);

                   

  font.Dispose;

  gr.Dispose;

  bitmap.Save(Response.OutputStream,

    ImageFormat.Jpeg);

  bitmap.Dispose();

end;

 

Conforme podemos observar na listagem anterior, o tipo de conteúdo de resposta do documento (Response.ContentType) será image/jpeg, ou seja uma imagem. Ainda salientamos que a imagem será descarregada de uma só vez, através do comando Response.BufferOutput = true.

Aqui usamos a classe Graphic para gerar a imagem. Através de seus métodos, como DrawString, DrawLine e FillRectangle criamos a imagem desejada dentro de um objeto Bitmap.

 

Entendendo o conteúdo da imagem

Conforme dito anteriormente, gerar a mensagem não é o suficiente, pois existem robots que acessam a URL de sua imagem com o intuito de rastreá-la e obter o conteúdo da mesma.

A primeira ação que devemos tomar é no sentido de criar uma imagem o mais randômica possível, ou seja, que menos possua padrões de posicionamento de caracteres, de tamanho de fonte etc.

No código anterior, veja que os tamanhos da fonte dos caracteres de validação não possuem um tamanho fixo, justamente para evitar que um robot seja configurado para rastrear o conteúdo de uma imagem cujo tamanho da fonte é conhecido.

Seguindo o mesmo raciocínio, a string de validação é “desenhada” na imagem. Novamente não temos um posicionamento definido para a mesma. Com esse cuidado evitamos que um robot acesse um ponto cardinal específico, onde ele saiba que a nossa string desenhada está localizada.

A seguir são tomadas ações para que a imagem não fique somente com os caracteres de validação impressos. Nesse caso, são inseridas algumas linhas inclinadas na horizontal, e a seguir um loop que “sorteia” pontos da tela, onde são inseridos pixels.

Tudo isso para, justamente, não deixar a imagem com um padrão de formatação que possa ser previsto. Ao acessarmos a URL da imagem (Figura 3), podemos observar que a mesma não possui um padrão determinado, o que certamente torna o seu sistema mais seguro.

 

Figura 3. Exemplos de imagens geradas

 

Inserindo a validação no formulário de votação

Volte à página Default.aspx e crie um layout semelhante ao da Figura 1. Adicione um Image e altere a propriedade ImageURL para o WebForm, que na realidade gera o conteúdo no formato de uma imagem jpeg (digite “image.aspx”). Adicione um TextBox para a digitação da string de validação e um Label para apresentar o resultado da validação. Veja como ficou a página na Figura 4.

 

Figura 4.  Inserindo a imagem no formulário de votação

 

Validando o conteúdo da imagem

Adicione o código da Listagem 3 no evento Click do botão. Aqui simplesmente testamos se o valor digitado no TextBox corresponde ao valor armazenado em sessão. Ou seja, a digitação foi válida. Veja na Figura 5 o resultado da aplicação em execução.

 

 

Listagem 3. Validando o conteúdo da imagem

if txtValidacao.Text = Convert.ToString(Session[

  'strValidation']) then

  lblResultado.Text :=

    'Seu voto foi computado com sucesso!'

else

  lblResultado.Text := 'Seu voto é inválido!';

 

Figura 5. Validando o conteúdo digitado pelo usuário

 

Dicas para incrementar a sua imagem de validação

O código apresentado para a geração da imagem é uma sugestão, pois a verdadeira intenção é apresentar técnicas de proteção para sua aplicação. Conforme vimos anteriormente, a imagem gerada deve ser a mais randômica possível, ou seja, apesar de apresentar um número fixo de caracteres, esses devem ser apresentados de forma não previsível.

Para tanto, incrementos como fazer com que a aplicação alterne o tipo da fonte usada, alternância das cores, rotação, tanto do background, como da fonte e dos outros elementos, são ações que podem auxiliar ainda mais na segurança.

Lembre-se, ainda, que a legibilidade do conteúdo a ser validado é muito importante, pois o usuário precisa reconhecer visualmente os caracteres que vai submeter à validação, claro.

 

ClubeDelphi PLUS!

Acesse agora o mesmo o portal do assinante ClubeDelphi e assista a uma vídeo-aula de Luciano Pimenta que mostra como usar um componente para validação de imagens.

 www.devmedia.com.br/articles/viewcomp.asp?comp=4378

Conclusão

As aplicações que ficam disponíveis na Web devem ser protegidas para que os recursos de servidor estejam sempre acessíveis. Para tanto, é imprescindível que as técnicas aqui apresentadas sejam submetidas a uma análise que gradue o nível de segurança necessário que deve ser incorporado à solução desenvolvida.

É necessário, também, que o desenvolvedor analise e incremente, sempre que possível, o algoritmo de geração de imagem, para que suas técnicas não fiquem obsoletas (ou conhecidas) e para que eventuais vulnerabilidades sejam detectadas e corrigidas.

 

 
Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Ficou com alguma dúvida?