OWASP Top 10 (2025): As Vulnerabilidades Web Mais Críticas

Guia completo do OWASP Top 10 com exemplos reais, código vulnerável vs seguro e como testar cada vulnerabilidade web crítica.

MundiX Team·24 de março de 2026·12 min de leitura

OWASP Top 10 (2025): As Vulnerabilidades Web Mais Críticas

O OWASP Top 10 é o documento de referência mais importante para segurança de aplicações web. Publicado pela Open Web Application Security Project (OWASP), ele lista as dez categorias de vulnerabilidades mais críticas e prevalentes em aplicações web. Neste guia, vamos explorar cada categoria em profundidade, com exemplos reais de código vulnerável, técnicas de teste e recomendações de correção que todo desenvolvedor e pentester brasileiro precisa conhecer.

O Que é a OWASP?

A OWASP (Open Worldwide Application Security Project) é uma fundação sem fins lucrativos dedicada a melhorar a segurança de software. Seus projetos incluem guias, ferramentas e metodologias utilizadas globalmente. O Top 10, atualizado periodicamente, é baseado em dados reais coletados de centenas de organizações e milhões de aplicações.

A01:2021 - Broken Access Control (Controle de Acesso Quebrado)

Descrição

O controle de acesso quebrado é a vulnerabilidade mais crítica da lista. Ocorre quando uma aplicação não verifica adequadamente se o usuário tem permissão para realizar determinada ação ou acessar determinado recurso.

Exemplo do Mundo Real

Em 2023, uma grande fintech brasileira sofreu um incidente onde clientes conseguiam acessar extratos bancários de outros clientes simplesmente alterando o ID na URL. Esse tipo de falha, conhecida como IDOR (Insecure Direct Object Reference), é extremamente comum.

Código Vulnerável vs. Seguro

python
# VULNERAVEL: Acesso direto sem verificacao de permissao
@app.route('/api/usuario/<int:user_id>/extrato')
def get_extrato(user_id):
    extrato = db.query("SELECT * FROM extratos WHERE user_id = %s", user_id)
    return jsonify(extrato)

# SEGURO: Verificacao de permissao antes do acesso
@app.route('/api/usuario/<int:user_id>/extrato')
@login_required
def get_extrato(user_id):
    if current_user.id != user_id and not current_user.is_admin:
        abort(403)
    extrato = db.query("SELECT * FROM extratos WHERE user_id = %s", user_id)
    return jsonify(extrato)

Como Testar

  • Tente acessar recursos de outros usuários alterando IDs na URL
  • Teste IDOR em todos os endpoints da API
  • Verifique se APIs REST verificam permissões em cada operação CRUD
  • Teste escalação vertical (acessar funções de admin como usuário comum)
  • Teste escalação horizontal (acessar dados de outro usuário do mesmo nível)

Como Corrigir

  • Implemente controle de acesso no servidor, nunca apenas no frontend
  • Use o princípio do menor privilégio
  • Desabilite listagem de diretórios no servidor web
  • Registre falhas de acesso e alerte administradores
  • Implemente rate limiting para APIs

A02:2021 - Cryptographic Failures (Falhas Criptográficas)

Descrição

Anteriormente chamada de "Sensitive Data Exposure", essa categoria abrange falhas na proteção de dados sensíveis em trânsito e em repouso, incluindo uso de algoritmos obsoletos, chaves fracas e ausência de criptografia.

Exemplo do Mundo Real

Aplicações que armazenam senhas com MD5 ou SHA1 sem salt, ou que transmitem dados sensíveis via HTTP sem TLS, são exemplos clássicos desta categoria.

Código Vulnerável vs. Seguro

python
# VULNERAVEL: Hash MD5 sem salt
import hashlib

def salvar_senha(senha):
    hash_senha = hashlib.md5(senha.encode()).hexdigest()
    db.execute("INSERT INTO usuarios (senha) VALUES (%s)", hash_senha)

# SEGURO: bcrypt com salt automatico e custo adequado
import bcrypt

def salvar_senha(senha):
    salt = bcrypt.gensalt(rounds=12)
    hash_senha = bcrypt.hashpw(senha.encode('utf-8'), salt)
    db.execute("INSERT INTO usuarios (senha) VALUES (%s)", hash_senha)

def verificar_senha(senha, hash_armazenado):
    return bcrypt.checkpw(senha.encode('utf-8'), hash_armazenado)

Como Testar

  • Verifique se dados sensíveis são transmitidos via HTTPS
  • Analise se senhas são armazenadas com algoritmos fortes (bcrypt, Argon2)
  • Teste se certificados SSL/TLS estão válidos e bem configurados
  • Verifique se dados de cartão de crédito seguem o PCI DSS

Como Corrigir

  • Use TLS 1.2+ para todos os dados em trânsito
  • Use bcrypt, scrypt ou Argon2id para hashing de senhas
  • Classifique dados por sensibilidade e aplique criptografia adequada
  • Não armazene dados sensíveis desnecessariamente
  • Desabilite cache para respostas com dados sensíveis

A03:2021 - Injection (Injeção)

Descrição

Vulnerabilidades de injeção ocorrem quando dados não confiáveis são enviados a um interpretador como parte de um comando ou consulta. Os tipos mais comuns incluem SQL Injection, NoSQL Injection, OS Command Injection e LDAP Injection.

Exemplo do Mundo Real

SQL Injection continua sendo uma das vulnerabilidades mais exploradas globalmente. Em 2024, diversas empresas brasileiras foram comprometidas por ataques de SQL Injection automatizados contra sistemas legados.

Código Vulnerável vs. Seguro

python
# VULNERAVEL: SQL Injection via concatenacao de string
@app.route('/busca')
def buscar():
    termo = request.args.get('q')
    query = f"SELECT * FROM produtos WHERE nome LIKE '%{termo}%'"
    resultado = db.execute(query)
    return jsonify(resultado)

# SEGURO: Consulta parametrizada (prepared statement)
@app.route('/busca')
def buscar():
    termo = request.args.get('q')
    query = "SELECT * FROM produtos WHERE nome LIKE %s"
    resultado = db.execute(query, (f'%{termo}%',))
    return jsonify(resultado)
sql
-- Payload de ataque SQL Injection
-- Input malicioso: ' OR '1'='1' --
-- Resultado: SELECT * FROM produtos WHERE nome LIKE '%' OR '1'='1' --%'
-- Isso retorna TODOS os registros do banco de dados

-- Input destrutivo: '; DROP TABLE usuarios; --
-- Resultado: deleta a tabela inteira de usuarios

Como Testar

bash
# Teste automatizado com SQLMap
sqlmap -u "https://alvo.com.br/busca?q=teste" --batch --level=3

# Payloads manuais comuns para teste
# ' OR '1'='1
# ' UNION SELECT null,null,null--
# '; WAITFOR DELAY '0:0:5'--

Como Corrigir

  • Use consultas parametrizadas (prepared statements) SEMPRE
  • Implemente ORM ao invés de queries SQL diretas quando possível
  • Valide e sanitize toda entrada de usuário
  • Use stored procedures quando apropriado
  • Implemente WAF como camada adicional de defesa

A04:2021 - Insecure Design (Design Inseguro)

Descrição

Essa categoria, introduzida em 2021, foca em falhas de design e arquitetura, não em falhas de implementação. Representa a ausência de controles de segurança no planejamento da aplicação.

Exemplo do Mundo Real

Um sistema de recuperação de senha que envia o link de reset sem rate limiting, ou uma API que permite listar todos os usuários sem paginação, são exemplos de design inseguro.

Padrões de Design Inseguro vs. Seguro

python
# DESIGN INSEGURO: Reset de senha sem rate limiting
@app.route('/esqueci-senha', methods=['POST'])
def esqueci_senha():
    email = request.form['email']
    token = gerar_token()
    enviar_email(email, token)
    return "Email enviado"
    # Problema: atacante pode enviar milhares de requisicoes

# DESIGN SEGURO: Com rate limiting, token seguro e resposta generica
from flask_limiter import Limiter

limiter = Limiter(app, key_func=get_remote_address)

@app.route('/esqueci-senha', methods=['POST'])
@limiter.limit("3 per hour")
def esqueci_senha():
    email = request.form['email']
    usuario = db.query("SELECT * FROM usuarios WHERE email = %s", email)
    if usuario:
        token = gerar_token_seguro(32)
        salvar_token_com_expiracao(token, usuario.id, expira_em=3600)
        enviar_email(email, token)
    # Sempre retorna a mesma mensagem (evita enumeracao de usuarios)
    return "Se o email existir em nossa base, enviaremos instrucoes."

Como Corrigir

  • Adote Threat Modeling desde o início do projeto
  • Use padrões de design seguros (Secure by Design)
  • Implemente limites de negócio (rate limiting, limites de tentativas)
  • Separe ambientes de desenvolvimento, teste e produção

A05:2021 - Security Misconfiguration (Configuração Incorreta)

Descrição

Configurações incorretas de segurança são extremamente comuns e incluem headers HTTP ausentes, serviços desnecessários habilitados, contas padrão ativas e mensagens de erro detalhadas expostas em produção.

Exemplo do Mundo Real

Servidores com DEBUG=True em produção, buckets S3 públicos e painéis administrativos acessíveis sem autenticação são achados frequentes em pentests no Brasil e no mundo.

Verificações Essenciais

bash
# Verificar headers de seguranca com curl
curl -I https://alvo.com.br

# Headers esperados na resposta:
# Strict-Transport-Security: max-age=31536000; includeSubDomains
# X-Content-Type-Options: nosniff
# X-Frame-Options: DENY
# Content-Security-Policy: default-src 'self'
# Referrer-Policy: strict-origin-when-cross-origin

# Verificar configuracao TLS
testssl.sh https://alvo.com.br

# Scan com Nuclei para misconfigurations
nuclei -u https://alvo.com.br -t misconfigurations/ -severity medium,high,critical

Como Corrigir

  • Implemente processo de hardening automatizado
  • Remova funcionalidades, frameworks e componentes não utilizados
  • Revise e atualize configurações regularmente
  • Use infrastructure as code para garantir consistência
  • Desabilite listagem de diretórios e stack traces em produção

A06:2021 - Vulnerable and Outdated Components (Componentes Vulneráveis)

Descrição

Aplicações frequentemente utilizam bibliotecas, frameworks e outros componentes de software com vulnerabilidades conhecidas. Essa categoria abrange a ausência de gerenciamento de dependências e atualizações de segurança.

Exemplo do Mundo Real

O incidente do Log4Shell (CVE-2021-44228) demonstrou como uma única dependência vulnerável pode comprometer milhões de aplicações globalmente.

Como Verificar

bash
# Python - verificar dependencias vulneraveis
pip audit

# Node.js - verificar dependencias vulneraveis
npm audit

# Java - verificar com OWASP Dependency Check
dependency-check --project "MeuProjeto" --scan ./lib/

# Verificar versoes de software expostas em servidores
nmap -sV -p 80,443 alvo.com.br

Como Corrigir

  • Mantenha inventário de todos os componentes e suas versões
  • Monitore continuamente por novas CVEs (NVD, GitHub Advisory Database)
  • Automatize atualizações com Dependabot ou Renovate
  • Remova dependências não utilizadas
  • Use apenas fontes confiáveis para componentes

A07:2021 - Identification and Authentication Failures (Falhas de Autenticação)

Descrição

Essa categoria cobre falhas que permitem a um atacante comprometer senhas, chaves, tokens de sessão ou explorar outras falhas de implementação para assumir a identidade de outros usuários.

Código Vulnerável vs. Seguro

python
# VULNERAVEL: Login sem protecao contra brute force
@app.route('/login', methods=['POST'])
def login():
    username = request.form['username']
    password = request.form['password']
    user = db.query("SELECT * FROM users WHERE username = %s", username)
    if user and check_password(password, user.password):
        session['user_id'] = user.id
        return redirect('/dashboard')
    return "Login invalido", 401

# SEGURO: Com rate limiting, timing constante e MFA
from flask_limiter import Limiter
import pyotp

@app.route('/login', methods=['POST'])
@limiter.limit("5 per minute")
def login():
    username = request.form['username']
    password = request.form['password']
    totp_code = request.form.get('totp_code')

    user = db.query("SELECT * FROM users WHERE username = %s", username)

    # Tempo constante para evitar timing attacks
    if not user or not bcrypt.checkpw(password.encode(), user.password):
        registrar_tentativa_falha(username, request.remote_addr)
        return "Credenciais invalidas", 401

    # Verificar MFA se habilitado
    if user.mfa_enabled:
        totp = pyotp.TOTP(user.mfa_secret)
        if not totp.verify(totp_code):
            return "Codigo MFA invalido", 401

    # Regenerar session ID para prevenir session fixation
    session.regenerate()
    session['user_id'] = user.id
    return redirect('/dashboard')

Como Corrigir

  • Implemente MFA (autenticacao multifator)
  • Nunca utilize credenciais padrão em produção
  • Implemente políticas de senha forte
  • Limite tentativas de login (rate limiting)
  • Use gerenciamento de sessão seguro com regeneração de token

A08:2021 - Software and Data Integrity Failures (Falhas de Integridade)

Descrição

Essa categoria foca em falhas relacionadas à integridade de software e dados, incluindo atualizações de software sem verificação de integridade, pipelines de CI/CD inseguros e deserialização insegura.

Exemplo: Deserialização Insegura

python
# VULNERAVEL: Deserializacao insegura com pickle
import pickle
import base64

@app.route('/carregar-perfil', methods=['POST'])
def carregar_perfil():
    dados = base64.b64decode(request.form['dados'])
    perfil = pickle.loads(dados)  # PERIGO: execucao de codigo arbitrario!
    return jsonify(perfil)

# SEGURO: Usar formato seguro como JSON com schema validation
import json
from marshmallow import Schema, fields

class PerfilSchema(Schema):
    nome = fields.Str(required=True, validate=lambda x: len(x) <= 100)
    email = fields.Email(required=True)

@app.route('/carregar-perfil', methods=['POST'])
def carregar_perfil():
    try:
        dados = json.loads(request.form['dados'])
        schema = PerfilSchema()
        perfil = schema.load(dados)
        return jsonify(perfil)
    except Exception:
        return "Dados invalidos", 400

Como Corrigir

  • Verifique integridade de software com assinaturas digitais
  • Use repositórios confiáveis para dependências
  • Implemente revisão de código para mudanças em CI/CD
  • Nunca use deserialização de dados não confiáveis (pickle, Java serialization)
  • Use SRI (Subresource Integrity) para recursos de terceiros no frontend

A09:2021 - Security Logging and Monitoring Failures (Falhas de Log e Monitoramento)

Descrição

Sem logging e monitoramento adequados, ataques não podem ser detectados nem investigados. Essa categoria abrange a ausência de logs de segurança, logs insuficientes e falta de alertas para eventos suspeitos.

Implementação de Logging Seguro

python
import logging
import json
from datetime import datetime

# Configurar logger de seguranca dedicado
security_logger = logging.getLogger('security')
security_logger.setLevel(logging.INFO)
handler = logging.FileHandler('/var/log/app/security.log')
handler.setFormatter(logging.Formatter('%(message)s'))
security_logger.addHandler(handler)

def log_evento_seguranca(tipo, descricao, usuario=None, ip=None, severidade="INFO"):
    evento = {
        "timestamp": datetime.utcnow().isoformat(),
        "tipo": tipo,
        "descricao": descricao,
        "usuario": usuario,
        "ip": ip,
        "severidade": severidade
    }
    security_logger.info(json.dumps(evento))

# Exemplos de uso em diferentes cenarios
log_evento_seguranca(
    tipo="LOGIN_FALHA",
    descricao="Tentativa de login com credenciais invalidas",
    usuario="admin",
    ip="192.168.1.100",
    severidade="WARNING"
)

log_evento_seguranca(
    tipo="ACESSO_NEGADO",
    descricao="Tentativa de acesso a recurso sem permissao",
    usuario="user123",
    ip="10.0.0.50",
    severidade="HIGH"
)

O Que Registrar

  • Tentativas de login (sucesso e falha)
  • Falhas de controle de acesso
  • Erros de validação de entrada (possíveis tentativas de injeção)
  • Alterações em dados sensíveis
  • Operações administrativas
  • Erros de aplicação e exceções não tratadas

Como Corrigir

  • Implemente logging centralizado (ELK Stack, Splunk, Graylog)
  • Configure alertas para eventos suspeitos
  • Retenha logs por período adequado (mínimo 90 dias, ideal 1 ano)
  • Proteja os logs contra adulteração
  • Realize revisão periódica dos logs

A10:2021 - Server-Side Request Forgery (SSRF)

Descrição

SSRF ocorre quando uma aplicação busca um recurso remoto sem validar a URL fornecida pelo usuário. Isso permite que o atacante force a aplicação a enviar requisições para destinos inesperados, incluindo serviços internos da infraestrutura.

Código Vulnerável vs. Seguro

python
# VULNERAVEL: SSRF - aplicacao busca qualquer URL fornecida
import requests

@app.route('/preview')
def preview():
    url = request.args.get('url')
    response = requests.get(url)  # PERIGO: acessa qualquer URL!
    return response.text

# Um atacante poderia acessar:
# /preview?url=http://169.254.169.254/latest/meta-data/ (AWS metadata)
# /preview?url=http://localhost:6379/ (Redis interno)
# /preview?url=file:///etc/passwd (arquivos locais)

# SEGURO: Validacao rigorosa com allowlist
from urllib.parse import urlparse
import ipaddress

DOMINIOS_PERMITIDOS = ['api.exemplo.com', 'cdn.exemplo.com']

def url_e_segura(url):
    try:
        parsed = urlparse(url)
        if parsed.scheme != 'https':
            return False
        if parsed.hostname not in DOMINIOS_PERMITIDOS:
            return False
        try:
            ip = ipaddress.ip_address(parsed.hostname)
            if ip.is_private or ip.is_loopback or ip.is_link_local:
                return False
        except ValueError:
            pass
        return True
    except Exception:
        return False

@app.route('/preview')
def preview():
    url = request.args.get('url')
    if not url_e_segura(url):
        return "URL nao permitida", 403
    response = requests.get(url, timeout=5)
    return response.text

Como Testar

bash
# Testar SSRF com payloads comuns
# Acessar metadata de cloud providers
curl "https://alvo.com.br/preview?url=http://169.254.169.254/latest/meta-data/"

# Acessar servicos internos
curl "https://alvo.com.br/preview?url=http://localhost:8080/admin"

# Bypass com redirecionamento
curl "https://alvo.com.br/preview?url=https://meu-servidor.com/redirect?to=http://localhost"

Como Corrigir

  • Implemente allowlist de URLs/domínios permitidos
  • Bloqueie requisições para redes internas e IPs reservados
  • Use firewall de saída para controlar conexões do servidor
  • Não retorne respostas brutas ao usuário
  • Desabilite redirecionamentos HTTP em requisições server-side

Ferramentas para Testar o OWASP Top 10

VulnerabilidadeFerramentas Recomendadas
Broken Access ControlBurp Suite, OWASP ZAP, testes manuais
Cryptographic Failurestestssl.sh, sslyze, Nmap scripts
InjectionSQLMap, Burp Suite, testes manuais
Insecure DesignThreat Modeling, revisão de arquitetura
Security MisconfigurationNuclei, Nikto, ScoutSuite (cloud)
Vulnerable Componentspip audit, npm audit, Dependency-Check
Auth FailuresHydra, Burp Intruder, testes manuais
Integrity FailuresVerificação de CI/CD, revisão de código
Logging FailuresRevisão manual, teste de detecção
SSRFBurp Collaborator, testes manuais

Conclusão

O OWASP Top 10 é um ponto de partida essencial, mas não uma lista exaustiva. A segurança de aplicações web requer uma abordagem contínua e em camadas, combinando desenvolvimento seguro, testes regulares e monitoramento constante. Para o mercado brasileiro, onde a transformação digital avança rapidamente, dominar essas vulnerabilidades é fundamental tanto para desenvolvedores quanto para profissionais de segurança.

Plataformas como o MundiX Web podem auxiliar na identificação e compreensão dessas vulnerabilidades, gerando comandos de teste e explicando conceitos de forma contextualizada durante seus engajamentos de pentest.

Comece Agora com MundiX

Quer testar suas aplicações contra o OWASP Top 10? O MundiX Web ajuda você a entender cada vulnerabilidade, gerar payloads de teste e interpretar resultados. Aprenda segurança de aplicações web de forma prática e guiada por inteligência artificial.

Acesse o MundiX Web e fortaleça a segurança das suas aplicações hoje mesmo.

📤 Compartilhar & Baixar