Executando verificação de segurança...
3

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

CamadaTecnologia
BackendPython 3 + Flask
Banco de dadosSQLite (.db)
ScrapingRequests + BeautifulSoup 4
TemplatesJinja2 + Tailwind CSS + Lucide Icons
TraduçãoGoogle Translate free tier + cache SQLite
IAGemini CLI (Google) com fallback para OpenCode CLI
SegurançaMó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=True para textos em inglês que contêm palavras portuguesas (ex: visao_geral de 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 é:

  1. Tenta Gemini CLI (gemini -p "prompt")
  2. Se falhar (quota, erro de rede), tenta OpenCode CLI (opencode run --dangerously-skip-permissions "prompt")
  3. Limpa meta-comentários da IA do output (frases como "Vou pesquisar...", "Com base nas informações...")
  4. Prefixa um disclaimer de geração por IA
  5. 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 TABLE só se não existirem
  • Executa limpezas e correções de dados via SQL puro
  • Usa a tabela config com chaves de controle para migrações destrutivas one-shot (ex: reset de flags translated)

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.txt e security.txt dinâmicos

SEO

Cada página tem schema JSON-LD adequado:

  • /WebSite + Organization + ItemList
  • /vazamentosCollectionPage + BreadcrumbList
  • /vazamentos/{id}NewsArticle + BreadcrumbList
  • /sobreAboutPage + FAQPage
  • /estatisticasDataCatalog

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=True na 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.


Projeto independente. Apenas fontes públicas. Nenhuma senha ou dado pessoal é divulgado.

Carregando publicação patrocinada...