Forced Browsing e Controle de Acesso no Cliente: A Página de Admin Escondida
O desafio
Este é um painel de cliente. O app esconde recursos de admin dos clientes com CSS, mas os links ainda vão na página que todo cliente baixa. Um deles é só para a equipe - leia a fonte e informe o endereço dessa página de admin.
O que você vai aprender
- Entender forced browsing e como atacantes chegam a páginas que nunca são linkadas na interface visível
- Reconhecer que esconder com CSS (display:none), itens de menu removidos e botões desabilitados são apresentação, não autorização
- Ler o HTML enviado como um atacante faria, tratando todo link e rota no código-fonte como acessível
- Explicar por que o controle de acesso deve existir no servidor, na própria rota, e não no navegador
- Relacionar essa fraqueza de controle no cliente com a categoria de controle de acesso quebrado nas vulnerabilidades web
Habilidades testadas
Pré-requisitos
- Familiaridade básica com links HTML e como um navegador carrega uma página
- Conforto usando o navegador para ver o código-fonte da página ou o inspetor de elementos
Como funciona
Forced browsing é o simples ato de requisitar uma página ou rota diretamente, mesmo quando nada na interface visível aponta para ela. Uma aplicação que esconde um controle com CSS - display:none, uma classe que colapsa um elemento, um item de menu removido no momento da renderização, ou um botão renderizado como desabilitado - mudou apenas o que o navegador pinta. O link, a URL e a rota subjacentes continuam presentes no HTML que todo visitante baixa. Qualquer um pode abrir o view-source ou um inspetor de elementos, ler o markup e seguir a rota manualmente.
O erro central é tratar o navegador como um limite de confiança. O navegador é totalmente controlado por quem o usa. CSS, bloqueios via JavaScript e nós do DOM escondidos são apresentação e conveniência, nunca segurança. Se a única coisa entre um cliente e uma página privilegiada é uma estilização que esconde o link, então a página privilegiada é efetivamente pública: está a uma inspeção e um clique de distância.
Este é o exemplo clássico de controle de acesso quebrado. O servidor serve alegremente a rota privilegiada para qualquer sessão autenticada porque nunca reverifica quem está pedindo. Esconder o ponto de entrada reduz a descoberta, mas descoberta não é autorização. No momento em que a rota é requisitada, o servidor precisa decidir se esta sessão específica tem permissão - e uma interface que apenas esconde links não toma essa decisão.
Erros comuns
- Assumir que, por um link não aparecer no menu, a rota por trás dele é inacessível - o markup é enviado para todo navegador independentemente da estilização.
- Confiar em
display:none, um botão desabilitado ou um item de lista removido como controle de acesso, quando isso só muda o que é pintado, não o que é servido. - Adicionar checagens em JavaScript que escondem ou bloqueiam a interface para usuários que não são da equipe, esquecendo que o atacante controla o navegador e pode simplesmente pular o script.
- Confiar em um papel, flag ou valor de cookie enviado pelo cliente para decidir o que mostrar, em vez de consultar o papel real no servidor a cada requisição.
Como se proteger
Aplique a autorização no servidor, na própria rota, em toda requisição. Antes de servir qualquer página ou ação privilegiada, o servidor deve ler a sessão autenticada, consultar o papel real desse usuário em um armazenamento confiável e rejeitar a requisição quando o papel não for permitido. Feito corretamente, um link revelado ou adivinhado simplesmente leva a uma negação, então vazar o link no HTML deixa de importar.
- Proteja toda rota de admin com uma checagem de papel no servidor (negar por padrão; permitir só sessões verificadas da equipe).
- Reverifique a autorização também nos endpoints de ação, não só na página que os renderiza, já que atacantes chamam esses endpoints diretamente.
- Nunca confie em um valor de papel ou permissão enviado pelo cliente; derive-o da sessão no servidor.
- Trate o esconderijo no cliente como uma conveniência de usabilidade sobre as checagens reais do servidor, nunca como substituto delas.