O OWASP Top 10 é a referência mais usada sobre riscos de segurança em aplicações web, e o OWASP Top 10 2025 é a sua oitava edição. Foi apresentado em novembro de 2025 no OWASP Global AppSec e está publicado em top10.owasp.org. Segundo a OWASP, esta edição analisou 589 CWEs com dados de mais de 2,8 milhões de aplicações, e duas das dez categorias vieram de uma pesquisa com a comunidade, e não dos dados brutos.
Neste guia passamos pelas dez categorias. Para cada uma você vê o que significa na prática, um trecho vulnerável, a versão corrigida e como detectar o problema no seu próprio código.
A lista OWASP Top 10 2025
| 2025 | Categoria | Mudança vs 2021 |
|---|---|---|
| A01 | Broken Access Control | Continua #1, agora inclui SSRF |
| A02 | Security Misconfiguration | Sobe do #5 |
| A03 | Software Supply Chain Failures | Nova, amplia Vulnerable and Outdated Components |
| A04 | Cryptographic Failures | Cai do #2 |
| A05 | Injection | Cai do #3 |
| A06 | Insecure Design | Cai do #4 |
| A07 | Authentication Failures | Renomeada (antes Identification and Authentication Failures) |
| A08 | Software or Data Integrity Failures | Mesma posição |
| A09 | Security Logging and Alerting Failures | Renomeada, foco em alertas |
| A10 | Mishandling of Exceptional Conditions | Nova |
A grande leitura de 2025: o risco saiu de "meu código tem um bug" para "minha configuração, minhas dependências e meu pipeline têm um bug". Duas das três primeiras categorias são coisas que um code review tradicional quase não olha.
A01: Broken Access Control
Usuários que conseguem ver ou fazer o que não deveriam: ler a fatura de outro cliente, chamar um endpoint de admin ou trocar um ID na URL e receber dados de outra pessoa (IDOR). Em 2025 a OWASP também incorporou aqui o Server-Side Request Forgery (SSRF), porque no fundo é o servidor acessando um recurso que não deveria.
// Vulnerável: qualquer usuário logado lê qualquer fatura
app.get("/api/invoices/:id", auth, async (req, res) => {
const invoice = await Invoice.findById(req.params.id);
res.json(invoice);
});
// Corrigido: a query fica restrita ao usuário atual
app.get("/api/invoices/:id", auth, async (req, res) => {
const invoice = await Invoice.findOne({ _id: req.params.id, userId: req.user.id });
if (!invoice) return res.status(404).end();
res.json(invoice);
});Como detectar: escreva testes que façam login como o usuário A e peçam recursos do usuário B. Scanners que só procuram padrões sofrem aqui, porque o bug é uma verificação que falta. Você precisa de ferramentas que entendam o fluxo entre request, sessão e query, além de rodadas de pentest com IA ou manual nos endpoints sensíveis.
A02: Security Misconfiguration
Modo debug em produção, credenciais padrão, CORS permissivo demais, páginas de erro verbosas, buckets públicos. Subiu para o #2 porque apps modernos são em grande parte configuração: recursos de cloud, containers, arquivos de CI e settings do framework.
# Vulnerável (Terraform): um bucket que qualquer pessoa na internet pode ler
resource "aws_s3_bucket_acl" "reports" {
bucket = aws_s3_bucket.reports.id
acl = "public-read"
}
# Corrigido: privado e com acesso público bloqueado explicitamente
resource "aws_s3_bucket_public_access_block" "reports" {
bucket = aws_s3_bucket.reports.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}Como detectar: scan de Infrastructure as Code em todo pull request (Terraform, manifestos de Kubernetes, Dockerfiles, workflows do GitHub Actions), mais um DAST básico para headers e páginas de erro na aplicação rodando.
A03: Software Supply Chain Failures
A categoria nova que substitui e amplia "Vulnerable and Outdated Components". Cobre a cadeia inteira: dependências com CVEs conhecidos, pacotes maliciosos ou com typosquatting, pipelines de build comprometidos e actions de terceiros que rodam com acesso aos seus segredos.
# Vulnerável: referências mutáveis, qualquer coisa pode mudar sem você saber
"dependencies": { "some-lib": "*" }
- uses: some-org/deploy-action@main
# Corrigido: lockfile + versões exatas, actions fixadas em um commit SHA
"dependencies": { "some-lib": "4.2.1" } # faça commit do package-lock.json e instale com npm ci
- uses: some-org/deploy-action@3f1c2a9e8b7d6c5a4f3e2d1c0b9a8f7e6d5c4b3aComo detectar: o Software Composition Analysis (SCA) compara seus lockfiles com bases de CVEs conhecidos. Coloque no CI para que uma versão vulnerável não seja mergeada em silêncio, e revise os workflows procurando actions sem pin e permissions amplas demais.
A04: Cryptographic Failures
Dados sensíveis expostos por criptografia fraca ou ausente: senhas com hash MD5 ou SHA-1, dados trafegando em HTTP puro, chaves hardcoded, números aleatórios previsíveis para tokens.
# Vulnerável (Python): hash rápido e sem salt, trivial de quebrar
import hashlib
stored = hashlib.md5(password.encode()).hexdigest()
# Corrigido: algoritmo de hash de senha lento e com salt
from argon2 import PasswordHasher
ph = PasswordHasher()
stored = ph.hash(password)
ph.verify(stored, attempt) # lança exceção se não baterComo detectar: o SAST encontra algoritmos fracos, Math.random() usado para tokens e chaves hardcoded. Um secret scanner encontra chaves commitadas, inclusive as que foram apagadas depois mas continuam no histórico do git.
A05: Injection
Input não confiável interpretado como código ou query: SQL injection, NoSQL injection, command injection e cross-site scripting (XSS), que a OWASP inclui aqui. O caso de SQL está detalhado no nosso guia de SQL injection.
# Vulnerável: input do usuário concatenado no SQL
cursor.execute(f"SELECT * FROM users WHERE email = '{email}'")
# Corrigido: query parametrizada, o driver cuida do escape
cursor.execute("SELECT * FROM users WHERE email = %s", (email,))Como detectar: aqui o SAST brilha, porque consegue seguir o input desde um parâmetro do request até um sink perigoso. O DAST confirma de fora. Veja SAST e DAST para saber quando usar cada um.
A06: Insecure Design
Falhas na lógica, não na implementação. O código faz exatamente o que foi projetado para fazer, e o projeto é explorável. Exemplo clássico: um reset de senha com código numérico curto e sem limite de tentativas.
# Design vulnerável: código de 4 dígitos, sem expiração, tentativas ilimitadas
code = random.randint(1000, 9999)
if request.form["code"] == str(user.reset_code):
allow_reset(user)
# Design corrigido: token longo e aleatório, expiração, limite de tentativas
token = secrets.token_urlsafe(32)
user.reset_token_hash = sha256(token)
user.reset_expires_at = now() + timedelta(minutes=15)
# na verificação: checar expiração, comparar hashes em tempo constante, bloquear após 5 falhasComo detectar: nenhum scanner encontra falhas de design de forma confiável olhando só a sintaxe. Threat modeling antes de construir, revisão de fluxos como cadastro, reset e checkout, e pentest (veja o que é pentest) são as defesas realistas.
A07: Authentication Failures
Login e sessões fracos: credential stuffing sem rate limit, regras de senha fracas, sessões que nunca expiram e JWTs decodificados sem verificação.
# Vulnerável (PyJWT): a assinatura nunca é verificada
payload = jwt.decode(token, options={"verify_signature": False})
# Corrigido: verificar a assinatura e fixar o algoritmo permitido
payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])Como detectar: o SAST aponta verificações desativadas e configurações de sessão fracas. Teste os endpoints de login procurando rate limiting e enumeração de contas (mensagens diferentes para "usuário inexistente" e "senha incorreta").
A08: Software or Data Integrity Failures
Confiar em código ou dados sem verificar a integridade: desserialização insegura, auto-updates sem checagem de assinatura, plugins ou scripts carregados de fontes não confiáveis.
# Vulnerável: desserializar bytes do atacante pode executar código
data = pickle.loads(request.data)
# Corrigido: formato só de dados e validação do schema
data = json.loads(request.data)
order = OrderSchema().load(data) # rejeita campos e tipos inesperadosComo detectar: o SAST detecta desserializadores perigosos (pickle, ObjectInputStream no Java, loaders de YAML inseguros). No CI, verifique checksums ou assinaturas dos artefatos que você baixa.
A09: Security Logging and Alerting Failures
Se você não enxerga um ataque, não consegue responder. O nome de 2025 destaca os alertas: log que ninguém lê não conta. O erro oposto também é comum: logar segredos.
# Vulnerável: loga a senha e não registra logins que falharam
logger.info(f"login attempt {email} {password}")
# Corrigido: evento estruturado, sem segredos, alimenta uma regra de alerta
logger.warning("auth.login_failed", extra={"email": email, "ip": ip})
# alerta: mais de 20 auth.login_failed de um mesmo IP em 5 minutosComo detectar: revise quais eventos de segurança são logados (logins, acessos negados, ações de admin), procure segredos nos statements de log e dispare um alerta de verdade em staging para provar que funciona.
A10: Mishandling of Exceptional Conditions
Nova em 2025. Programas que não previnem, não detectam ou não respondem bem a situações incomuns: exceções não tratadas, mensagens de erro que vazam detalhes internos, transações pela metade e a pior de todas, falhar aberto (fail open).
# Vulnerável: se o serviço de permissões cair, todo mundo passa
try:
allowed = permissions.check(user, "delete_project")
except Exception:
allowed = True
# Corrigido: falhar fechado e registrar
try:
allowed = permissions.check(user, "delete_project")
except Exception:
logger.exception("permission check failed")
allowed = FalseComo detectar: procure blocos except/catch genéricos que mudam decisões de segurança, stack traces devolvidos ao cliente e rollbacks ausentes. Testes de injeção de falhas (faça uma dependência dar timeout e veja o que acontece) funcionam muito bem.
OWASP API Security Top 10
Se o que você entrega é principalmente uma API, confira também o OWASP API Security Top 10 (o que muita gente procura como "owasp top 10 api"). A edição mais recente é de 2023 e foca em riscos específicos de APIs:
- API1: Broken Object Level Authorization (BOLA)
- API2: Broken Authentication
- API3: Broken Object Property Level Authorization
- API4: Unrestricted Resource Consumption
- API5: Broken Function Level Authorization
- API6: Unrestricted Access to Sensitive Business Flows
- API7: Server Side Request Forgery
- API8: Security Misconfiguration
- API9: Improper Inventory Management
- API10: Unsafe Consumption of APIs
Repare que autorização aparece três vezes. Em APIs, bugs de controle de acesso são de longe o achado grave mais comum, o que bate com Broken Access Control continuar em #1 no OWASP Top 10 principal.
Como cobrir o OWASP Top 10 na prática
| Técnica | Melhor para |
|---|---|
| SAST | A01, A04, A05, A07, A08, A10 no código-fonte |
| SCA | A03, dependências com CVEs conhecidos |
| Secret scanning | A04, chaves e tokens vazados |
| Scan de IaC | A02, configurações incorretas de cloud, containers e CI |
| DAST | A02, A05, A07 de fora, com a aplicação rodando |
| Pentest / threat modeling | A01 e A06, lógica de negócio e design |
A resposta prática é rodar a parte automatizada a cada mudança, que é justamente a proposta do DevSecOps, e reservar o tempo humano para design e lógica. Um scanner de vulnerabilidades que lê o seu repositório cobre a maior parte da tabela de uma vez.
Por exemplo, com o Nurbak você conecta o GitHub e escaneia um repositório: o modelo de IA próprio e self-hosted do Nurbak analisa o código (a análise não envia seu código para a OpenAI nem para a Anthropic), aponta vulnerabilidades exploráveis com arquivo e linha, compara as dependências com CVEs conhecidos, sinaliza configurações incorretas de GitHub Actions, Docker, Terraform e Kubernetes, e encontra segredos no histórico do git. O scan gratuito mostra completos os 3 achados mais importantes, então você vê como seu repositório está frente ao OWASP Top 10 antes de decidir qualquer coisa.
Resumo
- O OWASP Top 10 2025 é liderado por Broken Access Control, Security Misconfiguration e Software Supply Chain Failures.
- SSRF agora faz parte do A01, e o A10 (Mishandling of Exceptional Conditions) é novo: nunca falhe aberto.
- Cada categoria pede uma técnica de detecção diferente; nenhuma ferramenta sozinha cobre as dez.
- Se você tem APIs, revise também o OWASP API Security Top 10.
- Comece com uma base automatizada: escaneie seu repositório e corrija primeiro os achados de maior impacto.
