Voltar para o blog

Pentest de API: Swagger, Docs Expostos e Enumeração

12/06/2026 25 min de leitura
Pentest de API: Swagger, Docs Expostos e Enumeração

Resumo:

  • APIs são a superfície de ataque que mais cresce em aplicações modernas, com dezenas de endpoints frequentemente não auditados.
  • A documentação Swagger exposta em produção é o ponto de entrada mais produtivo em um pentest de API, pois entrega o mapa completo da API sem esforço.
  • Frameworks como Swagger UI e ReDoc habilitam a interface automaticamente no deploy, e os times costumam esquecer de desabilitar antes da produção.
  • Os cinco testes essenciais em cada endpoint são: autenticação ausente, IDOR, HTTP methods não documentados, mass assignment e endpoints de debug/admin expostos.
  • As técnicas descritas devem ser aplicadas exclusivamente em contextos autorizados: bug bounty, contratos de pentest ativos ou ambientes de laboratório próprios.

 

APIs são a superfície de ataque que mais cresce. Toda aplicação moderna tem pelo menos uma, e a maioria tem dezenas de endpoints que nunca foram auditados. O ponto de entrada mais produtivo em qualquer engajamento de API é a documentação: um Swagger exposto entrega o mapa completo de tudo o que existe, incluindo os endpoints que o time de produto esqueceu de mencionar. Este guia ensina a encontrar essa documentação, entender o que ela revela e o que fazer com cada informação.

Atenção: as técnicas descritas neste artigo devem ser aplicadas exclusivamente em contextos autorizados: bug bounty com escopo definido, contratos de pentest ativos ou ambientes de laboratório próprios. Acesso não autorizado a sistemas de terceiros é crime.

Por que a documentação de API é o melhor ponto de partida

A maioria das vulnerabilidades em APIs não está em algoritmos criptográficos complexos, nem em zero-days de framework. Está em endpoints que não têm autenticação, em parâmetros que não têm validação e em objetos que retornam mais dados do que deveriam. Para explorar essas falhas, o pentester precisa primeiro saber que os endpoints existem.

É aqui que a documentação de API se torna o ativo mais valioso de um engajamento. Um Swagger exposto entrega o equivalente ao código-fonte da API: todos os endpoints, todos os métodos HTTP aceitos, todos os parâmetros e seus tipos, os schemas de resposta, e frequentemente exemplos de payload. Um desenvolvedor pode ter gastado meses escrevendo a API, e o Swagger documenta cada detalhe em um arquivo JSON que qualquer pessoa pode ler.

O problema é que esse arquivo frequentemente fica acessível em produção por padrão, sem nenhum controle de acesso. Frameworks como Swagger UI, ReDoc e Springdoc habilitam a interface gráfica automaticamente no deploy. O time não desabilita porque usa internamente para testes, fazendo com que qualquer pessoa com o URL certo tenha o mapa completo da API.

O que um Swagger exposto entrega ao pentester?

  • A lista completa de todos os endpoints da API, incluindo os não linkados na interface.
  • Métodos HTTP aceitos por cada endpoint (GET, POST, PUT, DELETE, e PATCH).
  • Parâmetros obrigatórios e opcionais com tipos e exemplos.
  • Schemas de request e response com todos os campos.
  • Códigos de erro documentados que revelam a lógica interna.
  • Descrições que frequentemente mencionam comportamentos de segurança.

Passo 1: Encontrando a documentação de API

O primeiro passo é localizar a documentação. Ela pode estar em vários formatos: Swagger UI (a interface gráfica interativa), ReDoc (outra interface gráfica), o arquivo JSON ou YAML bruto do OpenAPI, ou uma coleção do Postman publicada. Cada um desses tem seus próprios paths previsíveis.

Paths mais comuns para tentar manualmente

Antes de rodar qualquer ferramenta, tente os paths mais comuns no browser ou no Burp. A maioria das documentações está em um desses locais e é encontrada em menos de dois minutos. Substitua alvo.com pelo host do alvo e tente cada um:

 

// Paths para testar

# Swagger UI (interface grafica)

/swagger

/swagger-ui

/swagger-ui.html

/swagger-ui/index.html

/swagger/index.html

/api/swagger

/api/swagger-ui

/api/swagger-ui.html




# OpenAPI / JSON / YAML

/swagger.json

/swagger.yaml

/openapi.json

/openapi.yaml

/api-docs

/api-docs.json

/api/docs

/api/openapi

/api/openapi.json

/api/v1/swagger.json

/api/v2/swagger.json

/v1/swagger.json

/v2/openapi.json




# ReDoc e outros visualizadores

/redoc

/redoc.html

/docs

/documentation

/api-reference




# Spring Boot (Java)

/v2/api-docs

/v3/api-docs

/v3/api-docs/swagger-config

/springdoc/v3/api-docs




# FastAPI (Python)

/docs          <- Swagger UI padrão do FastAPI

/redoc         <- ReDoc padrão do FastAPI

/openapi.json  <- JSON padrão do FastAPI




# Laravel (PHP)

/api/documentation

/docs/api




# NestJS (Node.js)

/api            <- Swagger UI padrão

/api-json       <- JSON do OpenAPI

 

swagger-jacker: automatizando a descoberta

Quando os paths manuais não retornam, o swagger-jagger é a ferramenta específica para descoberta de documentação de API. Ela tem uma wordlist dedicada com centenas de paths conhecidos para Swagger, OpenAPI, ReDoc e outras interfaces de documentação, e verifica cada um rapidamente.

 

// swagger-jacker

# Instalação do swagger-jacker

pip3 install swagger-jacker

# ou via git:

git clone https://github.com/BishopFox/swagger-jacker

cd swagger-jacker && pip3 install -r requirements.txt




# Uso básico: varrer todos os paths conhecidos

python3 swagger_jacker.py --url https://alvo.com




# Com autenticação (se a API requer token para acessar a documentação)

python3 swagger_jacker.py --url https://alvo.com \

  --header "Authorization: Bearer TOKEN"




# Salvando o resultado em arquivo

python3 swagger_jacker.py --url https://alvo.com --output docs_encontrados.txt




# Verificar sub domínios separados que podem ter APIs diferentes

python3 swagger_jacker.py --url https://api.alvo.com

python3 swagger_jacker.py --url https://backend.alvo.com

python3 swagger_jacker.py --url https://internal.alvo.com




# Quando encontrar, swagger-jacker exibe:

# [+] Found: https://alvo.com/api-docs (200 OK)

# [+] Found: https://alvo.com/swagger.json (200 OK)

 

Outros lugares onde a documentação aparece

Além dos paths padrão, existe documentação de API em lugares que muitos pentesters não procuram. Cada um desses é igualmente valioso:

  • Repositórios do GitHub públicos: buscar swagger, json ou postman_collection em repositórios da empresa. Coleções do Postman exportadas acidentalmente são muito comuns.
  • Google Dorks: site:alvo.com “swagger”, site:alvo.com filetype:json “openapi”, site:alvo.com inurl:api-docs. O Google pode ter indexado a documentação mesmo que ela não esteja linkada na navegação.
  • JavaScript da aplicação: buscar no bundle JS por “/api-docs”, “swagger”, “openapi”. O frontend pode referenciar a URL da documentação em algum link de ‘developer docs’ ou painel admin.
  • Headers HTTP: alguns servidores retornam links para a documentação no header Link ou em headers customizados como X-API-Docs.
  • Postman API Network: alguns times publicam coleções no Postman público. Buscar em postman.com pelo nome da empresa.
  • Wayback Machine: se a documentação existia antes e foi removida, pode estar arquivada. Acessar archive.org e buscar pelos paths de swagger do domínio.

Dica de decon passivo

Antes de fazer qualquer request ao alvo, busque no Google: site:alvo.com swagger OU site:alvo.com openapi OU site:alvo.com api-docs. Leva 30 segundos e frequentemente retorna resultados diretos. Se a documentação está indexada, você nem precisa da wordlist.

Passo 2: O que ler primeiro quando encontrar o Swagger

Encontrar o Swagger é apenas o início, o que você faz nos primeiros minutos depois de encontrá-lo determina quais endpoints você vai testar. Não comece testando aleatoriamente: leia o Swagger de forma estratégica, procurando pelos endpoints de maior risco antes de qualquer outro.

Endpoint categories de maior risco

A primeira leitura do Swagger deve ser uma varredura visual por categorias. Os endpoints de maior risco têm padrões reconhecíveis nos nomes:

Padrão NO ENDPOINT POR QUE TESTAR PRIMEIRO
/admin, /internal, /management Endpoints administrativos frequentemente sem autenticação ou com autorização fraca
/{id}, /{userId}, /{orderId} IDs numéricos ou UUIDs: IDOR potencial. Substituir pelo ID de outro usuário.
/export, /download, /report Exportação de dados frequentemente sem verificação de ownership.
/search, /query, /filter Parâmetros de busca: injeção de SQL, NoSQL ou operadores não esperados.
/upload, /import, /bulk Upload de arquivos: path traversal, SSRF, execução de código.
/delete, /remove, /reset Ações destrutivas: verificar se requerem privilégio e confirmação.
/config, /settings, /preferences Configurações: frequentemente retornam dados que não deveriam.
/token, /key, /secret, /auth Endpoints de autenticação: força bruta, enumeração, bypass.
/webhook, /callback, /notify Callbacks externos: SSRF potencial via URL controlada pelo usuário.
/debug, /test, /dev, /health Endpoints de desenvolvimento que não deveriam existir em produção.

 

O que verificar no schema de cada endpoint

Para cada endpoint de alto risco identificado, abra o schema de request e response no Swagger. Procure por quatro itens específicas:

  1. Campos que parecem ser IDs de outros recursos (IDOR potencial).
  2. Campos que aceitam URLs (SSRF potencial)
  3. Campos de role ou privilégio no request (mass assignment potencial).
  4. Campos sensíveis na response que não deveriam estar visíveis (vazamento de dados).

 

// Swagger Schema

// Exemplo de schema Swagger a analisar:

// GET /api/usuário/{id}




// Response schema que merece atenção:

{

  "id": 42,

  "name": "Joao Silva",

  "email": "joao@empresa.com",

  "role": "user",             <- esse campo está no response? posso alterar via PUT?

  "internal_id": "USR-001",   <- ID interno: pode vazar informação sobre outros usuários

  "subscription_plan": "free",

  "api_key": "sk_live_abc",   <- chave de API na response? Crítico

  "password_hash": "...",      <- hash de senha na response? Crítico

  "created_by": 1,             <- ID do admin que criou: IDOR para enumerar admins

  "team_id": 5                 <- ID de time: testar acesso a outros times

}




// POST /api/usuário/{id}/atualizar - request schema:

{

  "name": "string",

  "email": "string",

  "role": "string",        <- esse campo no request? mass assignment potencial

  "is_admin": "boolean",   <- idem

  "webhook_url": "string"  <- URL no request? SSRF potencial

Versões de API e endpoints legados

Uma das descobertas mais produtivas em qualquer Swagger é a existência de múltiplas versões da API. Frequentemente a versão atual (/api/v2/) tem controles de segurança mais robustos, enquanto a versão anterior (/api/v1/) ainda está ativa e tem validações mais fracas. Isso acontece porque as versões antigas são mantidas para compatibilidade retroativa com clientes existentes, mas recebem menos atenção de segurança.

O padrão a observar: se o Swagger documenta a v2, verifique manualmente se a v1 ainda responde. E se documentar apenas a v1, verifique se existe uma v2 ou v3 não documentada. Endpoints não documentados na versão atual, mas presentes na versão antiga, são frequentemente os mais vulneráveis.

 

// Versionamento de API

// Versões de API a verificar além das documentadas:

// Se o swagger documenta: /api/v2/usuários

// Testar:

/api/v1/usuários        <- versão anterior, talvez com menos segurança

/api/v3/usuários        <- versão nova não documentada?

/api/usuários           <- sem versão (pode ser alias para qualquer versão)

/v1/usuários

/v2/usuários




// Outros padrões de versionamento a verificar:

/api/2024/usuários      <- versionamento por data

/api/beta/usuários      <- versão beta

/api/internal/usuários  <- versão interna não documentada

/api/legacy/usuários    <- endpoints legados




// Headers de versão (alguns APIs usam header em vez de path):

GET /api/usuários HTTP/1.1

API-Version: 1    <- testar versões diferentes no header

Accept: application/vnd.empresa.v1+json  <- Content Negotiation


Passo 3: Importando o Swagger no Burp e no Postman

Depois de encontrar e analisar o Swagger, o próximo passo é importá-lo em uma ferramenta que permita testar cada endpoint de forma sistemática. Tanto o Burp Suite quanto o Postman aceitam arquivos OpenAPI/Swagger diretamente.

Importando no Postman para exploração inicial

O Postman importa arquivos OpenAPI 3.0 e Swagger 2.0 automaticamente, gerando uma coleção com todos os endpoints pré-configurados. Isso elimina o trabalho manual de criar cada request do zero. Para importar: File > Import > colar a URL do /swagger.json ou fazer upload do arquivo. O Postman gera automaticamente uma coleção com todas as pastas organizadas por tags do Swagger.

Com a coleção importada, configure uma variável de ambiente para a URL base e os tokens de autenticação. Depois, percorra os endpoints de alto risco identificados na etapa anterior. Para cada um, teste primeiro sem autenticação (deletar o header Authorization), depois com autenticação de usuário comum tentando acessar recursos de outros usuários.

Usando o Burp com o Swagger

O Burp Suite Pro tem suporte nativo a arquivos OpenAPI via Extensions > BApp Store > OpenAPI Parser. Depois de instalar, vá em Target > OpenAPI Parser, cole a URL do swagger.json ou faça upload do arquivo. O Burp gera automaticamente requests no Repeater para cada endpoint documentado, com os parâmetros pré-preenchidos com valores de exemplo.

Uma técnica muito útil: use o Burp Intruder em conjunto com a lista de endpoints do Swagger para testar IDOR em escala. Configure o Intruder para iterar sobre IDs numéricos em endpoints como /api/usuários/{id}, com o payload sendo uma sequência de 1 a 1000. Qualquer resposta com conteúdo diferente de 404 ou 403 é uma candidata a IDOR.

 

// Burp Suite

// Workflow Burp + Swagger:




// 1. Encontrar o swagger.json

GET https://alvo.com/swagger.json -> salvar localmente




// 2. No Burp: Extensions > OpenAPI Parser > Import

// O Burp gera um Site Map com todos os endpoints




// 3. Para cada endpoint de interesse:

// Clicar com botão direito > Send to Repeater




// 4. No Repeater, testar:

// a) Sem header Authorization (autenticação ausente?)

// b) Com token de usuário comum (acesso a admin?)

// c) Com ID de outro usuário no path




// 5. Usar Intruder para IDOR em escala:

GET /api/usuários/§1§ HTTP/1.1

Authorization: Bearer TOKEN_USUARIO_COMUM




// Payload: Numbers 1 to 500, step 1

// Flag: Status 200 e resposta com conteúdo




// Filtros no Intruder para IDOR:

// Grep - Match: "email", "phone", "document"  <- campos sensíveis

// Grep - Extract: content from response

// Filter: mostrar apenas status 200


Passo 4: Os testes que todo endpoint documentado merece

Teste 1: Autenticação ausente

O teste mais básico é o que mais frequentemente revela problemas. Para cada endpoint que você quer testar, envie a requisição sem nenhum header de autenticação. Se o servidor responder com dados em vez de 401 ou 403, a autenticação está ausente naquele endpoint. Isso é especialmente comum em endpoints de leitura (GET) que o desenvolvedor julgou “não sensíveis”, mas que retornam dados de todos os usuários.

 

// Burp Repeater

// Teste simples de autenticação ausente no Burp Repeater:




// Requisição original (com autenticação):

GET /api/v1/usuários HTTP/1.1

Authorization: Bearer TOKEN_VALIDO




// Teste sem autenticação (deletar o header):

GET /api/v1/usuários HTTP/1.1

// (sem Authorization)




// Resultados:

// HTTP 401 -> autenticação correta

// HTTP 200 com lista de usuários -> Crítico: sem autenticação




// Testar também com token inválido ou expirado:

GET /api/v1/usuários HTTP/1.1

Authorization: Bearer TOKEN_INVALIDO_OU_EXPIRADO




// HTTP 401 -> token validado

// HTTP 200 -> token não está sendo verificado


Teste 2: IDOR (Insecure Direct Object Reference)

Qualquer endpoint com um ID no path ou como parâmetro de query é candidato a IDOR. O teste padrão: autenticar como usuário A (ID 42), acessar um recurso que pertence ao usuário B (ID 1). Se o servidor retornar o recurso do usuário B usando o token do usuário A, o controle de acesso está ausente naquele endpoint.

O Swagger facilita muito essa identificação porque lista explicitamente todos os parâmetros de cada endpoint, incluindo os que ficam no path. Um endpoint como GET /api/pedidos/{orderId} deixa claro que orderId é testável para IDOR.

 

// Burp Repeater

// Encontrar endpoints com IDs no Swagger:

// Procurar por parâmetros do tipo: {id}, {userId}, {orderId}, {documentId}, etc.




// Exemplos encontrados no Swagger:

GET /api/pedidos/{orderId}

GET /api/documentos/{documentId}/download

GET /api/usuário/{userId}/dados-pessoais

DELETE /api/comentarios/{commentId}




// Teste de IDOR para cada um:

// Usuário autenticado: ID 42




// Acessar recurso do usuário 1 (admin, geralmente):

GET /api/pedidos/1 HTTP/1.1

Authorization: Bearer TOKEN_USUARIO_42




// Acessar recurso sequencial (ID menor = geralmente mais antigo/sensível):

GET /api/documentos/1/download HTTP/1.1

Authorization: Bearer TOKEN_USUARIO_42




// IDOR em parâmetro de query (não apenas no path):

GET /api/relatorio?usuario_id=1 HTTP/1.1

Authorization: Bearer TOKEN_USUARIO_42




// IDOR em body de POST:

POST /api/transferencia HTTP/1.1

{"de_conta": 42, "para_conta": 1, "valor": 0.01}

// Tentar: {"de_conta": 1, "para_conta": CONTA_ATACANTE, ...}

Teste 3: HTTP Methods não documentados

O Swagger documenta os métodos HTTP que cada endpoint deveria aceitar, mas o servidor pode aceitar métodos adicionais que o desenvolvedor não documentou nem restringiu. Um endpoint documentado como GET pode aceitar DELETE, e um endpoint documentado como POST pode aceitar PUT com semântica diferente.

O teste é simples: para cada endpoint encontrado no Swagger, tente os métodos que ele não documenta. Use o Burp Repeater para trocar o método HTTP e observe as respostas. Um status 200 em um método não documentado merece uma investigação imediata.

 

// Burp Repeater

// O Swagger documenta: GET /api/usuários/{id}

// Testar os métodos não documentados:




// Deletar usuário sem ser admin?

DELETE /api/usuários/42 HTTP/1.1

Authorization: Bearer TOKEN_USUARIO_COMUM




// Sobrescrever dados do usuário?

PUT /api/usuários/42 HTTP/1.1

Content-Type: application/json

{"role": "admin", "email": "atacante@email.com"}




// Atualizar parcialmente?

PATCH /api/usuários/42 HTTP/1.1

{"is_admin": true}




// Verificar métodos aceitos com OPTIONS:

OPTIONS /api/usuários/42 HTTP/1.1

// Response: Allow: GET, OPTIONS

// Se listar métodos além do GET: testar todos




// Verb tampering com X-HTTP-Method-Override:

GET /api/usuários/42 HTTP/1.1

X-HTTP-Method-Override: DELETE

// Alguns frameworks honram esse header




// POST tunnel para métodos bloqueados por firewall:

POST /api/usuários/42 HTTP/1.1

X-HTTP-Method-Override: PUT

Teste 4: Mass assignment via campos extras

O Swagger documenta os campos que o endpoint aceita no request. Mas se o servidor usar um ORM que mapeia o request body diretamente para um objeto do banco de dados, pode aceitar campos extras não documentados que o Swagger não lista. Enviar campos como role: admin, isAdmin: true ou accountStatus: verified pode resultar em escalada de privilégio se o servidor não fizer whitelist dos campos permitidos.

 

// Burp Repeater

// O Swagger documenta para POST /api/usuário/atualizar:

// { "name": "string", "email": "string" }




// Teste de mass assignment: enviar campos extras não documentados

POST /api/usuário/atualizar HTTP/1.1

Content-Type: application/json




{

  "name": "Teste",

  "email": "teste@email.com",

  "role": "admin",               <- não documentado, mas testável

  "is_admin": true,              <- idem

  "subscription": "enterprise",  <- idem

  "credits": 99999,              <- idem

  "email_verified": true,        <- idem

  "account_status": "active"     <- idem

}




// Se algum desses campos for refletido na response ou

// mudar o comportamento da conta: mass assignment confirmado




// Identificar campos a testar:

// 1. Inspecionar a response de GET do mesmo objeto

//    (campos na response que não estão no request do Swagger)

// 2. Procurar em erros de validação (o servidor pode listar campos rejeitados)

// 3. Tentar campo por campo para isolar qual é aceito


Teste 5: Endpoints de “debug” e “admin” expostos

Uma categoria específica que o Swagger frequentemente lista sem aparente preocupação: endpoints marcados como ‘internos’, ‘debug’ ou ‘admin’. Quando o Swagger está exposto publicamente, esses endpoints ficam documentados para qualquer um. Verifique se eles têm autenticação e se esta é verificada corretamente.

PROCURAR POR: /debug, /health/detailed, /admin/*, /internal/*, /actuator/*

ONDE: Swagger de qualquer API, especialmente Spring Boot (actuator) e frameworks com endpoints de healthcheck

POR QUE: Endpoints de admin frequentemente expostos sem autenticação. Spring Boot Actuator expõe /actuator/env com variáveis de ambiente, /actuator/beans com beans Spring, /actuator/httptrace com histórico de requests.

 

// Spring Boot / Debug

// Spring Boot Actuator: endpoints críticos a verificar

/actuator              <- lista todos os endpoints ativos

/actuator/env          <- variáveis de ambiente (pode ter senhas, chaves)

/actuator/beans        <- beans Spring (mapa da aplicação)

/actuator/httptrace    <- Histórico de requests HTTP recentes

/actuator/heapdump     <- dump de memória (pode conter dados em memória)

/actuator/logfile      <- arquivo de log

/actuator/mappings     <- todos os endpoints registrados no Spring




// Se /actuator retornar 200: verificar cada um dos sub-endpoints

curl https://alvo.com/actuator | python3 -m json.tool




// Outros endpoints de debug comuns:

/debug/info

/debug/vars            <- go pprof / expvar

/debug/pprof           <- profiler do Go (não deve estar em produção)

/metrics               <- métricas de sistema

/status

/info

/__admin               <- Wiremock admin

/console               <- H2 console, Rails console, etc.

Passo 5: Quando não existe Swagger, como enumerar endpoints?

Nem toda API tem Swagger exposto. Quando a documentação não é encontrada, o trabalho de enumeração passa a ser ativo: descobrir endpoints pela observação do tráfego, pelo comportamento da aplicação e pelo uso de wordlists especializadas para APIs.

Minerando endpoints do JavaScript

Aplicações SPA e frameworks modernos (React, Vue, Angular) fazem todas as chamadas de API via JavaScript. O código do bundle frequentemente tem URLs hardcoded. Abra o DevTools no Sources, use Ctrl+Shift+F e busque por “/api/”, fetch( e axios.. Cada resultado é um candidato.

 

// DevTools

// Buscas no bundle JavaScript para encontrar endpoints:




// No DevTools: Ctrl+Shift+F

// Termos para buscar:




"/api/"         -> endpoints com prefixo /api/

"/v1/"          -> endpoints versionados

"/v2/"

"fetch("        -> chamadas fetch()

"axios.get("    -> chamadas axios GET

"axios.post("   -> chamadas axios POST

".put("         -> chamadas PUT

".delete("      -> chamadas DELETE

"baseURL"       -> URL base da API

"API_URL"       -> variável com URL da API

"endpoint"      -> referências aos endpoints

"route"         -> definições de rotas




// Para cada string que parece um endpoint:

// Anotar o método HTTP associado (get, post, etc.)

// Anotar os parâmetros que aparecem junto




// Exemplo de trecho de bundle que revela endpoints:

// axios.get('/api/usuários/' + userId + '/pedidos')

// -> endpoint: GET /api/usuários/{id}/pedidos


Fuzzing com wordlists especializadas para API

O ffuf com wordlists especializadas para API produz resultados muito melhores do que wordlists genéricas de diretório. A SecLists tem uma coleção específica para APIs em Discovery/Web-Content/api/ que inclui nomes de endpoints comuns extraídos de APIs públicas reais.

 

// Shell / ffuf

# Wordlists específicas para API:

# /usr/share/seclists/Discovery/Web-Content/api/api-endpoints.txt

# /usr/share/seclists/Discovery/Web-Content/api/api-seen-in-wild.txt

# /usr/share/seclists/Discovery/Web-Content/api/objects.txt




# Fuzzing de API endpoints

ffuf -u https://alvo.com/api/FUZZ \

     -w /usr/share/seclists/Discovery/Web-Content/api/api-endpoints.txt \

     -H "Authorization: Bearer TOKEN" \

     -mc all -fc 404 -o api_endpoints.json




# Fuzzing de versões de API

ffuf -u https://alvo.com/FUZZ/usuários \

     -w api-versions.txt \

     -mc 200,201,301,401,403




# Wordlist de versões comuns:

# v1, v2, v3, api, api/v1, api/v2, rest, rest/v1, service, services




# Fuzzing de parâmetros em endpoints conhecidos

# Arjun descobre parâmetros escondidos

arjun -u https://alvo.com/api/usuários -m GET

arjun -u https://alvo.com/api/busca -m GET

arjun -u https://alvo.com/api/relatorio -m POST




# Kiterunner: especializado em API discovery

kr scan https://alvo.com -w routes-large.kite

kr scan https://alvo.com -w wordlist.txt --header "Authorization: Bearer TOKEN"

Lendo mensagens de erro para enumerar endpoints

Aplicações bem configuradas retornam 404 Not Found para qualquer endpoint que não exista. Mas muitas APIs retornam respostas diferentes para endpoints que existem, mas têm erro de autorização (401 ou 403) versus endpoints que simplesmente não existem (404). Essa diferença na resposta confirma que o endpoint existe, mesmo sem ver o conteúdo.

Além disso, mensagens de erro verbosas frequentemente revelam a estrutura da API. Um erro como ‘Resource not found for id 999’ confirma que o endpoint existe e aceita um parâmetro de ID. Um erro como ‘Missing required field: email’ confirma que o endpoint existe e qual campo é obrigatório. Leia cada mensagem de erro com atenção.

Findings típicos nesta metodologia

# FINDING SEVERIDADE ONDE ENCONTRAR
1 Swagger / OpenAPI exposto sem autenticação em produção ALTA Paths padrão (/swagger.json, /api-docs) ou swagger-jacker
2 API v1 ativa com menos controles que v2 documentada ALTA Tentar /api/v1/ quando Swagger documenta /api/v2/
3 IDOR em endpoint com ID no path: acesso a dados de outros CRÍTICA Swagger: endpoints com {id}, {userId}, etc. Trocar ID no Burp
4 Endpoint GET sem autenticação retornando lista de usuários CRÍTICA Testar cada GET documentado sem header Authorization
5 Mass assignment: campo role ou isAdmin aceito no PUT/PATCH CRÍTICA Adicionar campos extras não documentados no body do request
6 HTTP method não documentado aceito (ex: DELETE em GET only) ALTA Testar OPTIONS e depois cada método não listado no Swagger
7 Spring Actuator exposto: /actuator/env com variáveis de ambiente CRÍTICA Testar /actuator e sub-endpoints em qualquer app Java/Spring
8 Endpoint de exportação sem verificação de ownership ALTA Endpoints /export, /download, /report: testar com outro user_id
9 Chave de API ou token retornado em response (campo sensível) ALTA Schema de response no Swagger: buscar campos api_key, token
10 Endpoint de admin documentado sem autenticação CRÍTICA Tags admin, internal, management no Swagger

 

Checklist: o que cobrir em todo pentest de API

Descoberta da documentação

  • Paths padrão do Swagger testados manualmente no browser (5 minutos).
  • Google Dorks executados: site:alvo.com swagger / openapi / api-docs.
  • swagger-jacker executado contra o host principal e subdomains de API.
  • Repositórios do GitHub públicos buscados por swagger.json e coleções do Postman.
  • JavaScript da aplicação inspecionado por referências a documentação.

Análise do Swagger encontrado

  • Endpoints com padrões de alto risco identificados: /admin, /{id}, /export.
  • Schemas de resposta inspecionados por campos sensíveis não esperados.
  • Versões anteriores da API verificadas: /v1/ quando documenta /v2/.
  • Endpoints não linkados na UI, mas presentes no Swagger anotados.
  • Spring Actuator ou equivalente verificado em apps Java.

Testes em cada endpoint

  • Autenticação removida e endpoint testado sem Authorization.
  • ID de outro usuário substituído no path para teste de IDOR.
  • Métodos HTTP não documentados testados via OPTIONS + tentativa.
  • Campos extras enviados no body para teste de mass assignment.
  • Endpoints de exportação testados com IDs de outros usuários.

Quando não há Swagger

  • DevTools: Ctrl+Shift+F buscando /api/, fetch( e axios. no bundle JS.
  • Network tab: todos os endpoints /api/ listados durante uso normal.
  • ffuf com wordlists de API SecLists contra /api/.
  • Arjun executado em endpoints conhecidos para descobrir parâmetros.
  • Mensagens de erro analisadas: revelam existência de endpoints e campos

 

O Swagger exposto é o presente que o desenvolvedor deixa para o pentester. Em vez de semanas de enumeração ativa, você tem em segundos um mapa completo de toda a API: endpoints, métodos, parâmetros e schemas.

O que torna esse tipo de achado tão comum em produção é que o Swagger é genuinamente útil durante o desenvolvimento. O time usa internamente para entender a API, para testar endpoints durante o desenvolvimento e para o onboarding de novos desenvolvedores. O problema é que ninguém lembra de desabilitar antes do deploy, ou quando lembram, colocam autenticação, mas não testam se ela funciona.

A próxima vez que começar um pentest de API: antes de rodar ffuf, antes de analisar o JavaScript, dedique 5 minutos para tentar os paths padrão do Swagger. Se encontrar, os próximos 30 minutos de análise podem produzir mais achados do que horas de fuzzing cego.

Em engajamentos conduzidos pela Vantico, o Swagger exposto em produção aparece em mais da metade das aplicações testadas. O achado mais impactante não é a documentação em si, mas sim o que ela revela.

Em um engajamento recente, o Swagger exposto documentava um endpoint /api/admin/usuários sem mencionar autorização especial. Quando testado sem autenticação, retornou a lista completa de todos os usuários da plataforma com e-mails, telefones e dados de pagamento. A exposição existia há mais de dois anos.

 

A plataforma Vantico testa todos os endpoints documentados no Swagger a cada ciclo de sprint, garantindo que novos endpoints adicionados sem controle de acesso sejam identificados antes do próximo deploy.

Quer entender ainda mais sobre o pentest de APIs da Vantico? Clique aqui.

Siga a Vantico nas redes sociais e fique informado sobre cibersegurança, tecnologia e insights.

 


Júlia Valim Júlia Valim

Agende uma demonstração com a Vantico

Agendar demonstração