Formulários públicos na web são alvos constantes de scripts automatizados, spams e ataques de força bruta. Embora soluções de terceiros como reCAPTCHA e Turnstile sejam amplamente adotadas, muitos projetos exigem alternativas independentes para evitar scripts pesados de rastreamento, preservar a privacidade dos usuários ou simplesmente manter o controle total sobre o fluxo de validação. Nesse contexto, a criação de um captcha de texto case sensitive proprietário surge como uma barreira inicial direta e eficaz contra bots genéricos.
Contudo, a aparente simplicidade de exibir letras maiúsculas e minúsculas esconde armadilhas técnicas. Se o texto for inserido diretamente no HTML ou se a validação depender de lógicas frágeis, qualquer bot básico com OCR ou parser DOM contornará a proteção em milissegundos.
Princípios de Segurança para Captchas de Texto
Para que um captcha baseado em texto cumpra seu papel, três diretrizes arquiteturais precisam ser respeitadas:
- Geração Segura e Efêmera: O texto do desafio precisa ser gerado via gerador de números pseudoaleatórios criptograficamente seguro (como
random_bytesno PHP ou o módulocryptono Node.js). O segredo deve ter tempo de vida curto (TTL de 2 a 3 minutos). - Renderização em Imagem ou Vetor com Ruído: O texto nunca deve existir como string na resposta da requisição inicial. Ele deve ser desenhado em um canvas ou rasterizado em imagem (PNG/SVG distorcido) com linhas de interferência, rotação de caracteres e variação de fontes para dificultar o reconhecimento óptico automatizado.
- Uso Único (Anti-Replay): Cada token de validação deve ser destruído no primeiro teste, seja a tentativa correta ou incorreta. Isso impede que bots reutilizem um desafio previamente resolvido.
Arquitetura de Validação no Backend
Em sistemas que desenvolvo, costumo adotar uma abordagem desacoplada usando tokens assinados (HMAC) ou armazenamento em memória rápida (como Redis). O fluxo recomendado divide a responsabilidade entre apresentação e verificação estrita:
- Emissão do Desafio: O cliente requisita um novo captcha. O backend gera uma string aleatória (ex:
kR8vP), renderiza a imagem com distorção visual e associa o hash da string a um identificador único (ID da sessão ou UUID efêmero gravado no Redis com expiração automática). - Envio da Resposta: O usuário digita o texto exatamente como visualizado e envia o formulário com o UUID e a resposta.
- Comparação Estrita (Case-Sensitive): O backend busca o valor esperado referente àquele UUID. A comparação deve ser estrita, diferenciando maiúsculas de minúsculas (
kR8vP !== Kr8vp). Para prevenir ataques de temporização (timing attacks), recomenda-se o uso de funções de comparação em tempo constante, comohash_equalsoucrypto.timingSafeEqual. - Limpeza do Estado: Imediatamente após a verificação, o registro é removido da base temporária, forçando a emissão de um novo código em caso de falha.
Considerações de Usabilidade e Acessibilidade
O uso de distinção entre maiúsculas e minúsculas aumenta significativamente o espaço de busca contra ataques de dicionário e força bruta (62 combinações possíveis por caractere alfanumérico). No entanto, caracteres ambíguos como 0 (zero) e O (ó maiúsculo), ou l (ele minúsculo) e I (i maiúsculo), devem ser excluídos do alfabeto de geração para evitar frustração de usuários legítimos.
Além disso, recursos essenciais como um botão de atualização rápida da imagem e uma alternativa de áudio ou fallback acessível garantem que a proteção não se torne uma barreira intransponível para pessoas com deficiências visuais.
Estruturando a Defesa da Sua Aplicação
Implementar um mecanismo customizado de defesa contra bots exige equilíbrio entre fricção para o usuário e robustez criptográfica no servidor. Se a sua aplicação precisa de uma camada personalizada de proteção contra abusos sem depender de serviços externos, entre em contato para estruturarmos uma consultoria técnica focada na segurança dos seus fluxos de entrada.


