Manual de campo · 02 out 2026

Cada ferramenta, para que serve

Demo nas prints Programa Alvo Shop · shop.example.com · sessão A anônima, sessão B logada · achado IDOR em /v1/users/{id}

O Network Listener grava o tráfego do Chrome no seu servidor e mostra no dashboard o que o alvo já chamou. Este guia percorre cada tela com print de uma sessão de laboratório — o mesmo fluxo que você usa num programa com regras escritas.

Dashboard: network-listener.apps.gestaobem.com Repo: puppe1990/network-listener Prints: demo isolada, sem dado de produção

EX-00

Mapa das ferramentas

Quatro peças: extensão no Chrome (captura), servidor SQLite (guarda), dashboard (lê, compara, exporta) e o app desktop Tauri que empacota servidor + dashboard numa janela local. Tudo amarrado a um programa — o workspace com hosts permitidos e excluídos.

FerramentaPara que serveOnde
LoginEntra no dashboard com a conta admin (ou viewer).Dashboard
Popup da extensãoLiga captura e corpos, escolhe o programa, marca sessão, aponta o servidor.Ícone da extensão
App desktopJanela nativa que sobe o servidor local e abre o mesmo dashboard. SQLite no Application Support.apps/desktop-spike
Programa / workspaceDefine o alvo autorizado. Fora da lista, o corpo não grava e a linha sai como FORA DO ESCOPO.Header + popup
Ao vivoTimeline do que o browser fez: método, path, host, status, tipo.Nav Ao vivo
FiltrosRecorta por URL, host, tipo (Fetch/XHR, JS, Doc), método, status, erros, corpos.Barra acima da tabela
DetalheHeaders, cookie, token, corpo enviado e recebido de uma request.Clique na linha
ReplayReenvia a request (método, URL, headers, corpo) com a guarda de escopo.Painel do detalhe
Comparar 2 linhasDiff de URL, status, headers e corpos entre duas capturas.Checkboxes CMP
Nova sessãoMarca um instante. O inventário e o diff de sessões usam esses recortes.Popup · nova sessão
Comparar sessõesO que a API mostrou só em A, só em B, ou com status diferente.Nav Endpoints
Visto no JS/HTMLURL que o bundle cita e a sessão ainda não chamou.Nav Endpoints
InventárioSuperfície da API: path normalizado, GraphQL operationName, qtd, evidência.Nav Endpoints
AchadosCaderno local do bug, com requests anexadas e relatório Markdown.Nav Achados
Exportar dumpCSV ou HAR da sessão, com ou sem corpos, mascarando credenciais.Header · exportar
Importar HARJoga no programa um HAR do DevTools, Burp ou outro browser.Header · importar HAR
CifraCriptografa capturas em disco. Banner pede confirmação para apagar o claro.Banner no topo
Pesquisa só em ativo com programa e regras. O workspace existe para essa linha: hosts permitidos, resto sinalizado, corpo fora de escopo descartado.

EX-01

Login

Para que serve. Abre o dashboard. Super admin vê e apaga; viewer só lê (wipe, limpar e confirmar cifra ficam bloqueados).

O super admin nasce das variáveis SUPER_ADMIN_EMAIL e SUPER_ADMIN_PASSWORD no deploy. Oito falhas de senha no mesmo IP+e-mail em 15 min viram 429 com Retry-After.

Tela de login do Network Listener com campos de e-mail e senha e botão entrar.
Entrar com a conta de administrador para ver o tráfego capturado.

EX-03

App desktop

Para que serve. É a janela nativa do listener: sobe o Fastify + SQLite no seu Mac e abre o mesmo dashboard, sem depender do host de produção. Fecha a janela, o Node encerra junto e o banco fica no Application Support — sem processo órfão e sem WAL sujo.

Janela do app desktop Network Listener com o dashboard Ao vivo aberto.
Janela Tauri (título Network Listener, 1280×860). O conteúdo é o dashboard; a extensão continua gravando no Chrome.

O spike vive em apps/desktop-spike (fora do workspace npm e da CI). Tauri só inicia e encerra o backend TypeScript como filho — o servidor não foi reescrito em Rust.

cd apps/desktop-spike
npm run dev      # cargo tauri dev
npm run build    # .app + .dmg no macOS

A janela aponta para http://127.0.0.1:4820. Se a 4820 já estiver ocupada, o app para com diagnóstico em vez de um stack de EADDRINUSE; com PORT=0 o SO escolhe outra e você cola essa porta no popup, campo Servidor.

Onde o banco mora

macOS: ~/Library/Application Support/sh/network-listener/network-listener/network.db. Windows e Linux têm o equivalente em APPDATA / XDG, mas o bundle atual só gera .app e .dmg. Cifra em disco usa o Keychain no Mac, igual ao servidor solto.

Ainda é spike: sem instalador Windows/Linux, sem notarização, depende do Node 22 do sistema. A extensão MV3 continua obrigatória para capturar. Produção no Cleat segue em network-listener.apps.gestaobem.com.

EX-04

Programa (workspace)

Para que serve. É o contrato do alvo: nome, URL das regras, hosts permitidos, hosts excluídos. A sessão da extensão fica vinculada ao programa ativo. Trocar de programa com captura ligada pede confirmação.

No header: seletor Workspace, novo programa, bloquear (solta o vínculo até reabrir) e limpar programa (apaga capturas e achados daquele programa, com dois confirms). O formulário pede nome, URL das regras, hosts permitidos (obrigatório, aceita *.api.example.com), hosts excluídos e notas.

Na demo: permitidos shop.example.com, api.shop.example.com, cdn.shop.example.com. Excluído admin.shop.example.com — por isso GET /metrics aparece com o selo FORA DO ESCOPO e o corpo não entra.

Permitido

Corpo pode gravar

Host na lista allowed. Fetch/XHR com Corpos ligado. Replay só dispara se o destino continuar no escopo.

Excluído ou fora

Linha visível, corpo fora

A request ainda aparece na timeline para você ver o que o browser tocou. O conteúdo não é persistido.

EX-05

Ao vivo

Para que serve. É o rádio da sessão: cada request que passou pelo collector, com cards de volume, tempo médio, top hosts e taxa de erro.

Filtros no meio: busca por URL ou host, período, host, tipo (Fetch/XHR, Doc, JS…), método, faixa de status, “só erros”, “corpos”. A tabela mostra status, método, caminho, host, tipo, duração. Pausar a atualização congela o polling — útil na hora de marcar duas linhas para o diff.

Dashboard Ao vivo com 11 requisições, banner de cifra, filtros e tabela incluindo GET /metrics fora do escopo e GET /v1/users/41.
Timeline da demo. /metrics em admin.shop com selo FORA DO ESCOPO. IDOR candidato: GET /v1/users/41.

Header: bloquear, limpar programa, intervalo de atualização, atualizar, importar HAR, exportar, limpar base. Limpar base é wipe global — só super admin.

EX-06

Detalhe da request

Para que serve. Abre a prova: URL completa, request id, origem (captura ou import), escopo, headers (Authorization, cookie) e corpos. É daqui que você anexa evidência no achado e dispara o replay.

Painel de detalhe de GET /v1/users/41 com Authorization Bearer, cookie de sessão e headers Accept JSON.
GET /v1/users/41. Token e cookie à mostra porque Mascarar estava desligado na extensão.

Na mesma request a resposta veio {"id":41,"email":"bruno@lab.test","role":"admin"} autenticado como outro usuário — o IDOR da demo. Copiar URL e copiar request aceleram o relatório.

EX-07

Replay

Para que serve. Reenvia a captura contra o destino (método, URL, headers, corpo) para confirmar o bug sem montar o curl na mão. O servidor recusa destino fora do workspace ativo.

GET e HEAD seguem sem corpo (o fetch do Node rejeita body nesses métodos). Credenciais listadas embaixo do textarea de headers. O botão confirma o método e a URL antes de disparar.

Painel de replay com método GET, destino users/41, headers Authorization e cookie, e corpo da resposta com role admin.
Replay do IDOR. Resposta já no painel: bruno@lab.test, role admin.

EX-08

Comparar duas linhas

Para que serve. Marca duas requests na coluna CMP e o painel alinha URL, método, status, headers e corpos. JSON entra estrutural primeiro. Campos voláteis (ts, requestId, data.token) você ignora na caixa do topo.

Na demo: #7 GET /v1/users/me (eu) × #10 GET /v1/users/41 (outro id). Mesmo token, mesmo 200, path diferente, PII do admin no segundo.

Ao vivo com duas linhas marcadas, /v1/users/me e /v1/users/41, e painel comparar #7 × #10 aberto à direita.
Dois checks na coluna CMP abrem o diff. 13 requests depois da sessão B.
Painel comparar em close-up: url me versus users/41, ambos GET 200, mesmos headers Authorization e cookie.
Close-up do painel. Corpo enviado ausente nos dois GETs; a diferença mora na URL e na resposta.

EX-09

Comparar sessões

Para que serve. Mostra o que a API revelou antes e depois de um recorte (login, troca de conta, checkout). Cada “nova sessão” no popup vira um marco. A janela A é [marco 1, marco 2); a B é [marco 2, agora).

Três blocos: só na sessão A, só na sessão B, status mudou. GraphQL aparece com o operationName — na demo, GetCart no anônimo e GetOrders no logado.

Página Endpoints, bloco comparar sessões: só em A search/login/GetCart; só em B metrics, users, GetOrders, checkout e POST login.
Sessão A: busca e GetCart. Sessão B: login POST, /v1/users/me, /v1/users/{int}, GetOrders, checkout.

Os dois selects no canto escolhem quais marcos comparar se você marcou mais de dois.

EX-10

Visto no JS/HTML

Para que serve. Extrai URLs http(s) e caminhos /api/ dos bundles e documentos capturados. Só no JS é superfície que o front conhece e a sessão ainda não chamou. Chamado já apareceu na timeline.

Na demo o app.js cita /v1/export, /v1/internal/flags, /api/admin/users, /api/v1/search, /api/config.js. São os próximos alvos manuais — o listener aponta, você decide se chama (dentro do programa).

Seção visto no JS/HTML com tabela só no JS (export, flags, admin, search, config) e chamado (app.js).
Paths truncados na coluna; o hover e o detalhe da request #12/#13 mostram a URL completa.

EX-11

Inventário de endpoints

Para que serve. Compacta a sessão numa superfície de API: método + host + path normalizado (int, uuid, id opaco vira {int} / {uuid}). GraphQL ganha coluna de operação. Exporta CSV e JSON. Teto de 50 mil requests na agregação — o dashboard avisa se cortar.

Cada linha tem botão de evidência com o id da request, para pular no detalhe ou anexar no achado. Na demo, GET /v1/users/{int} é o IDOR; POST /graphql · GetOrders é a query autenticada.

Inventário de endpoints com 8 endpoints: metrics, GetOrders, checkout, users/{int}, users/me, app.js, home e POST login.
8 endpoints em 8 requests da janela do marco. CSV e JSON no canto.

EX-12

Achados

Para que serve. Caderno do bug no próprio programa: título, severidade, estado (confirmed, etc.), impacto, passos, evidências (requests por id). Relatório Markdown mascarado por padrão; “relatório com segredos” se você realmente precisa dos tokens. Nada sobe para plataforma externa.

Tela Achados com IDOR em GET /v1/users/{id}, severidade high, confirmed, evidência #10 e anexos #7 e #10.
IDOR high/confirmed. Evidência #10 (users/41). Anexar as selecionadas #7 e #10 fecha o par me × outro.

Novo achado pelo botão no canto. Excluir some só do caderno local. Viewer lê; quem escreve precisa de papel com write.

EX-13

Exportar dump

Para que serve. Tira a sessão do dashboard para um agente, um ticket ou o Burp. CSV para grep e planilha; HAR para replay em outra ferramenta.

Escolhas: com detalhes (headers e corpos) ou menos dados; recorte pelos filtros atuais, pela sessão marcada, ou janelas de 10 min até 12 h; só fetch/XHR; mascarar credenciais (authorization, cookie, x-goog-visitor-id — os corpos saem como foram gravados).

Diálogo exportar dump com CSV selecionado, com detalhes, filtros atuais, só fetch/XHR e mascarar credenciais, 8 linhas prontas.
8 linhas prontas com os filtros atuais. A sessão marcada no popup vira recorte “a sessão desde …”.

EX-14

Importar HAR

Para que serve. Entra no programa um HAR 1.2 do Chrome DevTools, Firefox, Safari ou Burp — tráfego que a extensão não viu (outro browser, curl via proxy do Burp, sessão antiga). Precisa de programa ativo; senão o botão fica desabilitado.

O arquivo tem que ser JSON. O dashboard mostra um resumo do que entrou. Origem da request no detalhe passa a “import” em vez de “captura”. Inventário, visto no JS e achados enxergam o import igual ao resto.

Proxy MITM local ficou de fora de propósito: HAR cobre o caso “vim de outra ferramenta”. Replay cobre o caso “quero reenviar esta linha”.

EX-15

Cifra em disco

Para que serve. No macOS a chave vive no Keychain; no Linux você passa NL_DATA_KEY. Capturas novas entram cifradas. O banner no topo avisa quantas linhas ainda estão em texto puro e pede confirmar cifra (apaga o claro) ou desfazer.

Viewer não confirma nem desfaz. Token de ingestão da extensão também não — só a conta admin do dashboard. Confirmar é irreversível para aquelas cópias em claro.

EX-16

Rota de uma sessão

Ordem que fecha o ciclo, da instalação ao relatório. As prints desta página seguem exatamente esses passos na demo Alvo Shop.

  1. Sobe o app desktop (apps/desktop-spike) ou aponta a extensão para o host do Cleat. No popup, o campo Servidor é http://127.0.0.1:4820 (janela local) ou https://network-listener.apps.gestaobem.com.
  2. Cria o workspace com a URL das regras e os hosts do escopo. Ativa. Só então a extensão associa a sessão.
  3. Servidor, token, Capturar e Corpos ligados, Mascarar a seu critério. Seleciona o programa. Testar conexão. Nova sessão (marco A).
  4. Home, busca, GraphQL público. Olha Ao vivo. Confere FORA DO ESCOPO. Nova sessão (marco B) antes do login.
  5. Login, /me, checkout, o que o app chamar. Endpoints → comparar sessões. GetCart vs GetOrders, users/me vs users/{int}.
  6. Inventário + visto no JS. Path normalizado, operationName, URLs que o bundle cita e você ainda não chamou.
  7. Detalhe, comparar duas linhas, replay no escopo. Anexa os ids no achado. Exporta o dump mascarado e o relatório .md.

Limites úteis

O listener é passivo: grava o que o browser (ou o HAR) já fez. Corpo teto 128 kB (150 kB no schema). Retenção padrão 3 dias (1–90), sweep de hora em hora. Lote da extensão: no máximo o batch e 2 MB por envio. Sem circuit breaker — fila local quando o servidor cai.

Papéis: super admin apaga e confirma cifra; viewer lê. Token de ingestão autentica a extensão e para no envio — wipe e confirmação de cifra ficam na conta do dashboard.