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
pythonimport 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
| Vulnerabilidade | Ferramentas Recomendadas |
|---|---|
| Broken Access Control | Burp Suite, OWASP ZAP, testes manuais |
| Cryptographic Failures | testssl.sh, sslyze, Nmap scripts |
| Injection | SQLMap, Burp Suite, testes manuais |
| Insecure Design | Threat Modeling, revisão de arquitetura |
| Security Misconfiguration | Nuclei, Nikto, ScoutSuite (cloud) |
| Vulnerable Components | pip audit, npm audit, Dependency-Check |
| Auth Failures | Hydra, Burp Intruder, testes manuais |
| Integrity Failures | Verificação de CI/CD, revisão de código |
| Logging Failures | Revisão manual, teste de detecção |
| SSRF | Burp 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.