Autorização e controle de acesso
Autenticação prova quem você é. Autorização decide o que você pode tocar. A falha mais comum e mais danosa em aplicações modernas é errar a segunda: um usuário autenticado lendo ou alterando dados que não são dele.
Checklist
- Verifique a propriedade em todo acesso a objetos. Para cada rota que recebe um id (uma fatura, uma nota, um projeto, uma mensagem), confirme que o usuário atual é dono ou pode acessar aquele registro específico antes de retorná-lo ou alterá-lo. Isso é Broken Object Level Authorization (BOLA), também chamado de IDOR, e é o risco número um da OWASP.
- Filtre pelo dono, não apenas pelo id. Uma consulta como
SELECT * FROM invoices WHERE id = ?é um IDOR. Transforme-a emWHERE id = ? AND owner_id = ?e retorne 404 quando não houver resultado. - Não conte com o cliente para esconder coisas. Um botão oculto ou um link ausente não é controle de acesso. A verificação deve estar no servidor.
- Mantenha a autorização ao refatorar. Verificações de acesso adicionadas em uma mudança costumam ser removidas na seguinte. Teste novamente a propriedade após cada alteração em rotas de dados.
- Aplique row-level security no banco de dados quando sua plataforma suportar, para que uma verificação esquecida no código ainda seja barrada pela camada de dados.
- Proteja todas as rotas administrativas e internas. Confirme que quem chama é realmente um administrador de uma fonte confiável (um papel no servidor, não um campo que o usuário possa definir), e mantenha as rotas exclusivamente internas inacessíveis pela internet pública.
- Isole os tenants. Em uma aplicação multi-tenant, toda consulta e todo caminho de arquivo devem ser restritos ao tenant de quem chama, por meio de um único ponto de controle, para que um cliente nunca alcance dados ou arquivos de outro.
- Confine os caminhos de arquivo. Quando uma requisição indica um arquivo, resolva-o e confirme que ele permanece dentro do diretório permitido, e que a verificação para em um separador de caminho, para que uma pasta irmã com nome mais longo não seja acessível.
Como testar
- Crie duas contas. Como conta A, solicite diretamente os ids de objetos da conta B. Nada de B deve voltar.
- Chame uma rota de administrador com o token de um usuário comum. Espere 403.
- Faça requisições com padrões
../e com caminhos de prefixo irmão em qualquer endpoint de arquivos.