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

2025CategoriaMudança vs 2021
A01Broken Access ControlContinua #1, agora inclui SSRF
A02Security MisconfigurationSobe do #5
A03Software Supply Chain FailuresNova, amplia Vulnerable and Outdated Components
A04Cryptographic FailuresCai do #2
A05InjectionCai do #3
A06Insecure DesignCai do #4
A07Authentication FailuresRenomeada (antes Identification and Authentication Failures)
A08Software or Data Integrity FailuresMesma posição
A09Security Logging and Alerting FailuresRenomeada, foco em alertas
A10Mishandling of Exceptional ConditionsNova

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@3f1c2a9e8b7d6c5a4f3e2d1c0b9a8f7e6d5c4b3a

Como 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 bater

Como 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 falhas

Como 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 inesperados

Como 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 minutos

Como 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 = False

Como 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:

  1. API1: Broken Object Level Authorization (BOLA)
  2. API2: Broken Authentication
  3. API3: Broken Object Property Level Authorization
  4. API4: Unrestricted Resource Consumption
  5. API5: Broken Function Level Authorization
  6. API6: Unrestricted Access to Sensitive Business Flows
  7. API7: Server Side Request Forgery
  8. API8: Security Misconfiguration
  9. API9: Improper Inventory Management
  10. 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écnicaMelhor para
SASTA01, A04, A05, A07, A08, A10 no código-fonte
SCAA03, dependências com CVEs conhecidos
Secret scanningA04, chaves e tokens vazados
Scan de IaCA02, configurações incorretas de cloud, containers e CI
DASTA02, A05, A07 de fora, com a aplicação rodando
Pentest / threat modelingA01 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.