Desativado mas Entregue: Lendo uma Ação de Exclusão em Formulário Desativado
O desafio
Este painel de administração deixa o botão 'Excluir usuário' acinzentado para que não possa ser clicado. Mas o formulário por trás dele ainda é entregue no HTML, action e tudo. Abra o código-fonte, encontre o endereço para onde a ação de exclusão envia e o submeta.
O que você vai aprender
- Entender que desativar um botão é um estado visual do lado do cliente, não uma verificação do servidor
- Ler a URL de action de um formulário no código-fonte da página
- Encontrar o endpoint de destino por trás de um controle que a interface deixou acinzentado
- Reconhecer que controles ocultos ou desativados ainda entregam seu destino ao cliente
- Explicar por que a autorização deve ser aplicada no lado do servidor em cada requisição
Habilidades testadas
Pré-requisitos
- Saber como abrir o código-fonte em um navegador
- Noção básica de que formulários enviam dados para uma URL (a action)
Como funciona
Interfaces web costumam esmaecer ou desativar um controle que o usuário atual não tem permissão para usar - um botão Delete user acinzentado, por exemplo. Isso parece uma medida de segurança, mas desativar um botão só impede um clique dentro daquele navegador. O formulário ao qual o botão pertence, incluindo a URL para a qual ele enviaria os dados (seu action), ainda faz parte do HTML que foi enviado à página.
Isso significa que o endpoint de destino pode ser lido no código-fonte, e pior, pode ser chamado diretamente. Neste desafio, o código-fonte mostra que a ação de exclusão aponta para /admin/users/delete, com um comentário admitindo que o botão está apenas "desativado no lado do cliente até role=owner." Um atacante não precisa habilitar o botão; ele pode enviar uma requisição diretamente para /admin/users/delete por conta própria. Se o servidor confia que a interface impediu a ação, a exclusão é realizada.
Este é um padrão clássico de controle de acesso quebrado: o frontend é decorativo. Botões ocultos, campos desativados e mensagens de "você não tem permissão" são dicas para o usuário, não aplicação de segurança. A única coisa que realmente impede a ação é o servidor revalidar, na própria requisição, que quem está chamando tem permissão para realizá-la.
Erros comuns
- Confiar no estado desativado. Presumir que um botão acinzentado significa que a ação não pode acontecer, quando apenas o clique foi bloqueado.
- Olhar só para o botão. Ler o rótulo do botão e não perceber a action do formulário e o comentário que revelam o endpoint real.
- Enviar para a rota errada. Digitar o link de reset ou de listagem em vez da URL da ação de exclusão.
- Presumir que campos ocultos são inertes. Ignorar o campo oculto e o comentário que carregam
/admin/users/delete.
Como se proteger
Nunca trate um controle desativado ou oculto como uma verificação de acesso. Aplique a autorização no servidor para toda requisição que altere estado, independentemente do que a interface mostrou.
- Revalide o papel e a permissão de quem está chamando no servidor, dentro do próprio endpoint de exclusão, em cada requisição.
- Não dependa de desativar, ocultar ou acinzentar controles para impedir uma ação - esses são apenas estados visuais.
- Exija que rotas que alteram estado usem o método de requisição correto e rejeite chamadas não autorizadas, mesmo que a URL seja conhecida.
- Evite vazar o destino da ação e a lógica de acesso em comentários e campos ocultos entregues ao cliente.