O Campo que Vence: Dois Campos, Um Nome, Uma Resposta

Fundamentos de Segurança Nível 3/4 ~4 min 2 de outubro de 2026

O desafio

A prefeitura de Brackwell paga seus voluntários por hora. Os pagamentos de um voluntário não batem com a folha de ponto impressa há quatro meses: a folha assinada pelo supervisor diz um número, a folha de pagamento diz outro, e o portal mostra o número assinado em todas as telas que alguém abre. Ninguém achou um jeito de editar uma folha já enviada. Esta é a página como o navegador a tinha no momento do envio do formulário. Leia o que o formulário realmente enviaria e informe o número de horas que o servidor aceitou.

O que você vai aprender

  • Identificar nomes de parâmetros duplicados no código-fonte de um formulário
  • Explicar como frameworks diferentes resolvem um parâmetro HTTP repetido
  • Separar o valor que uma página renderiza do valor que ela envia
  • Reconhecer um campo de relatório que lê dados diferentes dos que foram enviados
  • Descrever por que uma interface internamente consistente ainda pode estar errada

Habilidades testadas

Revisão de código-fonte no lado do clienteAnálise de parâmetros HTTPRaciocínio sobre lógica de negócio

Pré-requisitos

  • O que são um formulário HTML e um campo oculto (hidden input)

Como funciona

O HTTP não tem regra nenhuma dizendo que um parâmetro aparece uma única vez. Um formulário com dois campos compartilhando o mesmo nome envia os dois, e a requisição fica perfeitamente bem formada. O que a aplicação enxerga depende inteiramente de como o framework resolve essa repetição, e os frameworks discordam entre si: PHP e Rails ficam com a última ocorrência, o Express com seu parser padrão produz um array, o Flask devolve a primeira ocorrência via acesso por colchetes e a lista completa via getlist, e alguns load balancers e web application firewalls fazem esse parsing de um jeito diferente ainda do que o app por trás deles.

Essa discordância é a classe de bug em si. Ela importa mais quando uma ocorrência é visível e está sob o controle do usuário, e a outra é oculta e carrega um valor que significa dinheiro, permissão ou identidade. A correção que as pessoas costumam tentar, esconder o campo, não resolve nada: um campo oculto não é secreto nem somente leitura, ele só não é exibido na tela.

A segunda metade deste caso vale tanto quanto a primeira. Os relatórios leem hours_display, um campo diferente com um valor diferente, e por isso toda tela voltada para o usuário concordou consigo mesma por quatro meses. Quando dois caminhos de código leem dois campos que deveriam guardar a mesma coisa, mais cedo ou mais tarde eles vão discordar, e o campo que ninguém observa é o que decide.

Erros comuns

  • Responder 12. Esse é o campo visível e o número assinado, e é exatamente por isso que a discrepância ficou sem explicação por quatro meses.
  • Supor que o último campo vence. Verdade em PHP e Rails. O comentário no código menciona o Werkzeug, onde o acesso por colchetes devolve o primeiro.
  • Responder 418. total_hours_ytd é um total acumulado, e não é o campo que está sendo enviado para esta semana.
  • Ler somente a pré-visualização. Três dos campos que importam nunca aparecem na tela.

Como se proteger

Rejeite a ambiguidade em vez de resolvê-la.

  • Trate um parâmetro repetido como uma requisição malformada. Leia com getlist, e se a lista tiver mais de um item, retorne um 400 e registre isso em log.
  • Nunca envie um valor que o servidor consiga calcular sozinho. As horas pagas devem vir apenas do campo enviado, validado contra o registro de aprovação do supervisor no servidor.
  • Tenha um único campo de referência. Relatórios, exportações e a execução do pagamento devem ler o mesmo valor armazenado, para que uma divergência seja impossível em vez de apenas invisível.
  • Faça a checagem cruzada das saídas. Um relatório semanal comparando horas pagas com horas aprovadas teria detectado isso já na primeira folha de pagamento.

Solução completa

Membros Pro e Max desbloqueiam o passo a passo completo.

Assinar Pro

Estatísticas da comunidade

166 resoluções
88% taxa de sucesso
M2F14M3 Primeiro sangue

Hacks de hoje relacionados

34.000+ Hackers Labs reais Grátis
Comece Grátis ou resolva o hack de hoje, sem conta