Pitch: Criei uma plataforma que monitora vazamentos, vazamentos de dados, vítimas de ransomware da DarkWeb e tudo em português, com mais de 3000 registros praticamente em tempo real!
Construí um monitor de dark web em tempo real com Python, Flask e SQLite — e tudo em português
A maioria das ferramentas de threat intelligence é paga, em inglês e voltada para equipes de segurança com orçamento. Construí o Vazamentos da Dark Web (vazamentos.bnvd.org) como uma iniciativa independente para democratizar esse tipo de informação para o Brasil.
⚙️ Por trás, existe um sistema totalmente automatizado que:
• coleta informações de várias fontes da dark web
• identifica vazamentos e incidentes relevantes
• remove conteúdos duplicados
• traduz tudo para português
• organiza os dados de forma clara
• adiciona um contexto simples (IA) pra explicar o que aconteceu
Tudo isso rodando o tempo todo.
⏱️ Resultado?
Um painel atualizado quase em tempo real com o que está acontecendo no mundo.
Hoje, já são mais de 3.000 registros catalogados.
📊 Entre eles:
• vazamentos de dados corporativos e governamentais
• ataques de ransomware
• exposição de credenciais
• incidentes de segurança em diversos países
Mas o ponto principal não é o volume.
É o acesso.
🌎 Qualquer pessoa pode entrar e entender o cenário atual de ameaças.
Sem login. Sem pagar. Sem conhecimento técnico avançado.
🔐 E um ponto muito importante:
Nenhum dado sensível é exposto.
Nada de senhas. Nada de arquivos privados.
Apenas informações públicas organizadas com responsabilidade.
O problema que queria resolver
O Dark Web Informer é uma das fontes públicas mais completas de incidentes de segurança. O problema: tudo em inglês, sem contexto para o público brasileiro e sem forma de acompanhar o volume sem visitar o site manualmente.
Arquitetura geral
DarkWebInformer.com
│
▼
[Scraper — BeautifulSoup]
│ a cada 120s
▼
[Pipeline de enriquecimento]
├── Deduplicação por URL
├── Tradução EN→PT (Google Translate free + cache SQLite)
├── Extração de metadados estruturados
└── Geração de análise por IA (Gemini CLI / OpenCode CLI)
│
▼
[SQLite — .db]
│
▼
[Flask — Jinja2 + Tailwind CSS]
│
▼
Usuário final (vazamentos.bnvd.org)
Stack técnica
| Camada | Tecnologia |
|---|---|
| Backend | Python 3 + Flask |
| Banco de dados | SQLite (.db) |
| Scraping | Requests + BeautifulSoup 4 |
| Templates | Jinja2 + Tailwind CSS + Lucide Icons |
| Tradução | Google Translate free tier + cache SQLite |
| IA | Gemini CLI (Google) com fallback para OpenCode CLI |
| Segurança | Módulo próprio (rate-limit, headers OWASP, honeypot) |
Pipeline de coleta e enriquecimento
1. Scraper periódico
O scraper varre 3 categorias do DWI (data-breaches, ransomware, leaks) a cada 120 segundos em uma thread dedicada. Para cada artigo encontrado:
- Extrai título, categoria, data do incidente e URL
- Verifica duplicatas por URL antes de inserir
- Traduz título e metadados imediatamente
- Converte a data para
data_iso(YYYY-MM-DD) para ordenação cronológica correta
PADRAO_DATA = re.compile(
r"(January|February|...|December)\s+\d{1,2},\s+\d{4}"
)
def data_para_iso(data_texto: str) -> str:
m = re.match(r'([A-Za-z]+)\s+(\d{1,2}),\s+(\d{4})', data_texto or '')
if not m:
return ''
mes_num = _MESES_ISO.get(m.group(1), '')
return f"{m.group(3)}-{mes_num}-{int(m.group(2)):02d}" if mes_num else ''
2. Enriquecimento de detalhes
Uma segunda passagem busca os detalhes completos de cada artigo (página individual): resumo, metadados estruturados (país, setor, tipo de ataque, escopo, preço, rede Tor/I2P), screenshots e data/hora exata via JSON-LD.
3. Tradução com cache
Toda tradução passa pelo Translator, que:
- Usa o Google Translate free tier (
translate.googleapis.com) - Faz cache em tabela SQLite própria (
traducoes) para evitar chamadas repetidas - Detecta automaticamente se o texto já está em português (para não traduzir de volta)
- Aceita
force=Truepara textos em inglês que contêm palavras portuguesas (ex:visao_geralde artigos sobre organizações brasileiras) - Divide textos longos em chunks por parágrafo/sentença para respeitar o limite da API
def traduzir(self, texto: str, force: bool = False) -> str:
if not force and self._is_likely_portuguese(texto):
return texto
cached = self._get_cache(texto)
if cached:
return cached
traduzido = self._google_translate(texto)
if traduzido is not None: # não cacheia falhas de rede
self._set_cache(texto, traduzido or texto)
return traduzido or texto
4. Geração de análise por IA
Um worker dedicado (thread separada) percorre todos os registros sem visao_geral e gera um artigo analítico para cada um. O fluxo é:
- Tenta Gemini CLI (
gemini -p "prompt") - Se falhar (quota, erro de rede), tenta OpenCode CLI (
opencode run --dangerously-skip-permissions "prompt") - Limpa meta-comentários da IA do output (frases como "Vou pesquisar...", "Com base nas informações...")
- Prefixa um disclaimer de geração por IA
- Marca o registro com
ia_gerado = 1
O worker respeita rate-limits com pausas de 90 segundos entre gerações.
A ordenação usa data_iso DESC, id DESC — garantindo ordem cronológica pelo dia do incidente, não pelo timestamp de scraping. Isso evita o problema clássico de artigos históricos (raspados hoje) aparecerem no topo com datas de 2024.
Sistema de migração
Em vez de um sistema de migrations externo, uso um método _migrar() que roda a cada inicialização e é idempotente:
- Adiciona colunas novas com
ALTER TABLEsó se não existirem - Executa limpezas e correções de dados via SQL puro
- Usa a tabela
configcom chaves de controle para migrações destrutivas one-shot (ex: reset de flagstranslated)
Segurança
O módulo security.py implementa mais de 25 funções cobrindo:
- Rate limiting por IP (Flask-Limiter)
- Headers de segurança HTTP (CSP, HSTS, X-Frame-Options, etc.)
- Honeypot para bots (rotas falsas que retornam 404 mas registram o IP)
- Bloqueio de User-Agents maliciosos
- Proteção contra path traversal e injeção de parâmetros
- Geração de
robots.txtesecurity.txtdinâmicos
SEO
Cada página tem schema JSON-LD adequado:
/→WebSite+Organization+ItemList/vazamentos→CollectionPage+BreadcrumbList/vazamentos/{id}→NewsArticle+BreadcrumbList/sobre→AboutPage+FAQPage/estatisticas→DataCatalog
Sitemap XML gerado dinamicamente com todas as URLs, prioridade e changefreq por categoria.
O que aprendi
- SQLite aguenta mais do que parece. Com índices e queries bem escritas, 3.000+ registros com JSON embutido performam muito bem para um site de tráfego moderado.
- Cache de tradução é essencial. Sem ele, o scraper bateria no rate-limit do Google em poucos ciclos. Com cache, a maioria das chamadas é resolvida em microssegundos.
- Workers em thread separada mudam tudo. Separar scraping, enriquecimento e geração de IA em threads independentes eliminou o bloqueio do ciclo principal e melhorou muito a latência das rotas Flask.
force=Truena tradução. Textos sobre organizações brasileiras em inglês ("Banco X data breach", "governo dados") tinham palavras suficientes para o detector de português fazer falso positivo e pular a tradução. Um flag simples resolveu.
Links
- Site: vazamentos.bnvd.org
- Desenvolvido por: Juan Mathews Rebello Santos Juan Mathews Rebello Santos & Osvaldo Janeri (perito.digital)
Projeto independente. Apenas fontes públicas. Nenhuma senha ou dado pessoal é divulgado.
Fonte: https://vazamentos.bnvd.org/