Boas práticas e padrões · Segurança no código · 6 min de leitura
OWASP Top 10:2025 para quem programa
A lista dos riscos mais comuns em aplicações web, traduzida em hábitos de código: controle de acesso no servidor, configuração segura, dependências confiáveis, criptografia certa e erros tratados.
Arraste para o lado para ver o diagrama inteiro.
Os 10 riscos de 2025
- A01 Controle de acesso quebrado — confira no servidor, em cada endpoint, se este usuário pode ver este recurso (o id na URL não prova nada).
- A02 Configuração insegura — debug ligado, senhas padrão, CORS aberto, headers de segurança faltando.
- A03 Falhas na cadeia de suprimentos — dependências e ferramentas de build comprometidas ou desatualizadas: fixe versões, use lockfile, verifique e atualize.
- A04 Falhas de criptografia — HTTP sem TLS, hash de senha fraco (use Argon2/bcrypt), chave no código.
- A05 Injeção — SQL, XSS, comandos: parâmetros e escape.
- A06 Design inseguro — falta de limite de tentativas, regras de negócio que dá para pular.
- A07 Falhas de autenticação — sessão que não expira, sem MFA, recuperação de senha fraca.
- A08 Integridade de software e dados — atualizações e dados aceitos sem verificar assinatura; desserialização insegura.
- A09 Falhas de log e alerta — ataque acontecendo sem ninguém saber.
- A10 Tratamento incorreto de condições excepcionais — erros que vazam detalhes, falham "abertos" ou deixam o sistema num estado inconsistente.
Hábitos que cobrem a maior parte
- Negar por padrão e checar permissão no servidor, com teste automático para "usuário B não vê o pedido do usuário A".
- Parâmetros em todo SQL; escape automático em todo HTML.
- Dependências com lockfile, atualizadas e verificadas no CI.
- Erros tratados com resposta genérica para o cliente e detalhe só no log.
- Limite de taxa em login e endpoints caros.
No código: antes e depois
// Qualquer usuário logado vê o pedido de qualquer outro trocando o id (A01)
app.get('/pedidos/:id', autenticado, async (req, res) => {
const pedido = await db.pedidos.findById(req.params.id);
res.json(pedido);
}); app.get('/pedidos/:id', autenticado, async (req, res) => {
// O filtro pelo dono faz parte da consulta: sem permissão, nem chega a existir
const pedido = await db.pedidos.findOne({ id: req.params.id, donoId: req.usuario.id });
if (!pedido) return res.status(404).end(); // 404 não confirma que o pedido existe
res.json(pedido);
});
// Teste que protege a regra:
// it('usuário B não vê o pedido do usuário A', async () => {
// expect((await como(usuarioB).get(`/pedidos/${pedidoDeA.id}`)).status).toBe(404);
// }); A checagem de dono está na consulta e coberta por teste — o jeito de não esquecê-la no próximo endpoint.
Em resumo
- Controle de acesso no servidor, sempre.
- Configuração segura por padrão.
- Dependências fixas e verificadas.
- Erros tratados sem vazar detalhes.
Perguntar à IA
Monte um prompt pronto sobre OWASP Top 10:2025 para quem programa na sua linguagem e no seu caso, e abra num chat gratuito.
O prompt vai para o site que você escolher. Não cole senhas, tokens nem dados reais de clientes. Para Gemini e outros, copie e cole.