Análises Técnicas

Regras WAF da Cloudflare que desencadeiam desafios CAPTCHA

O Web Application Firewall (WAF) da Cloudflare permite que os operadores de sites criem regras que acionam desafios CAPTCHA com base em atributos de solicitação específicos — endereço IP, país, caminho de URL, pontuação de bot, cabeçalhos ou qualquer combinação. Compreender quais regras desencadeiam desafios ajuda a diagnosticar por que você está vendo um CAPTCHA e a escolher a abordagem certa para lidar com isso.


Ações de regras do WAF que produzem CAPTCHAs

As regras WAF da Cloudflare suportam diversas ações. Três deles apresentam desafios solucionáveis:

Ação WAF O que acontece Estado HTTP Método CaptchaAI
Desafio Gerenciado Cloudflare decide: desafio invisível, Turnstile ou JS 503 turnstile
Desafio JS Página de desafio JavaScript de 5 segundos 503 turnstile_staging
Desafio Interativo CAPTCHA tradicional (legado, obsoleto) 403 turnstile
Bloquear Difícil 403, sem desafio 403 N/A (não solucionável)
Permitir Passe, sem cheque 200 N/A
Pular Ignorar as regras restantes do WAF 200 N/A
Registro Registrar evento, nenhuma ação 200 N/A

Desafio gerenciado (mais comum)

O Desafio Gerenciado é a ação recomendada pela Cloudflare. Ele decide de forma adaptativa o tipo de desafio por visitante:

WAF rule matches → Managed Challenge triggered
    ↓
Cloudflare evaluates visitor:
  ├─ Low risk → Invisible pass (no visible challenge)
  ├─ Medium risk → Turnstile widget (click to verify)
  └─ High risk → JavaScript challenge page
    ↓
Successful → cookie_qa_validacao cookie issued

Padrões comuns de regras do WAF

Os operadores do site criam regras WAF usando a linguagem de expressão da Cloudflare. Estes são os padrões com maior probabilidade de acionar CAPTCHAs para tráfego automatizado:

Regras de pontuação de bot

# Challenge traffic with low bot scores
(cf.bot_management.score lt 30)
→ Action: Managed Challenge

# Challenge non-verified bots
(cf.bot_management.score lt 50 and not cf.bot_management.verified_bot)
→ Action: JS Challenge

As regras de pontuação de bot são o gatilho mais comum para ferramentas de automação. Os solucionadores de API do CaptchaAI recebem pontuações de nível humano porque usam navegadores reais.

Regras baseadas no país

# Challenge traffic from specific countries
(ip.geoip.country in {"CN" "RU" "VN" "IN"})
→ Action: Managed Challenge

# Block specific regions entirely
(ip.geoip.country eq "XX")
→ Action: Block

Regras baseadas em caminho

# Challenge login page access
(http.request.uri.path eq "/login" or http.request.uri.path eq "/signup")
→ Action: Managed Challenge

# Challenge API endpoints
(http.request.uri.path contains "/api/")
→ Action: JS Challenge

Regras baseadas em taxas

# Challenge after high request rate
(cf.threat_score gt 10 and http.request.uri.path contains "/search")
→ Action: Managed Challenge

Regras baseadas em cabeçalho

# Challenge requests with no Accept-Language header
(not http.request.headers["accept-language"])
→ Action: JS Challenge

# Challenge requests with suspicious UA
(http.user_agent contains "python" or http.user_agent contains "curl")
→ Action: Managed Challenge

Regras compostas

# Multiple conditions
(cf.bot_management.score lt 30
 and http.request.uri.path contains "/api/"
 and ip.geoip.country ne "US")
→ Action: JS Challenge

Identificando qual regra foi acionada

Quando um desafio CAPTCHA aparece, você pode identificar a regra de acionamento na resposta:

Dos cabeçalhos HTTP

import requests

def check_cloudflare_rule_info(url):
    """Extract WAF rule information from Cloudflare Turnstile em staging response."""
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                      "AppleWebKit/537.36 Chrome/120.0.0.0",
        "Accept": "text/html,*/*;q=0.8",
        "Accept-Language": "en-US,en;q=0.9",
    }

    response = requests.get(url, headers=headers, timeout=15, allow_redirects=False)

    info = {
        "status": response.status_code,
        "cf_ray": response.headers.get("cf-ray", ""),
        "cf_cache_status": response.headers.get("cf-cache-status", ""),
        "server": response.headers.get("server", ""),
    }

    # Challenge-specific info
    html = response.text

    if response.status_code == 503:
        if "jschl" in html:
            info["challenge_type"] = "JS Challenge (IUAM or WAF rule)"
        elif "challenge-platform" in html:
            info["challenge_type"] = "Managed Challenge"
        elif "cf-turnstile" in html:
            info["challenge_type"] = "Turnstile (Managed Challenge)"

    elif response.status_code == 403:
        if "cf-ray" in str(response.headers):
            info["challenge_type"] = "WAF Block (no challenge)"
        else:
            info["challenge_type"] = "Origin 403 (not Cloudflare)"

    return info

Do Cloudflare Ray ID

Cada resposta da Cloudflare inclui um cabeçalho cf-ray. Os operadores do site podem usar esse Ray ID no painel da Cloudflare (Segurança > Eventos) para ver exatamente qual regra foi acionada e qual ação foi tomada.


Resolvendo desafios desencadeados pelo WAF

Estratégia baseada no tipo de desafio

import requests
import time

API_KEY = "YOUR_API_KEY"

def solve_turnstile_staging(url, challenge_type):
    """Solve Cloudflare Turnstile em staging based on WAF rule action."""

    if challenge_type == "managed_challenge":
        # Managed Challenge typically renders as Turnstile
        method = "turnstile"
        sitekey = extract_turnstile_sitekey(url)
    elif challenge_type == "js_challenge":
        # JavaScript Challenge page
        method = "turnstile_staging"
        sitekey = "managed"
    else:
        raise ValueError(f"Unknown challenge type: {challenge_type}")

    submit = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY,
        "method": method,
        "sitekey": sitekey,
        "pageurl": url,
        "json": 1,
    })

    task_id = submit.json()["request"]

    for _ in range(60):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY,
            "action": "get",
            "id": task_id,
            "json": 1,
        }).json()

        if result.get("status") == 1:
            return result["request"]

    raise TimeoutError("Challenge solve timed out")


def extract_turnstile_sitekey(url):
    """Fetch page and extract Turnstile sitekey."""
    import re
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                      "AppleWebKit/537.36 Chrome/120.0.0.0",
    }
    response = requests.get(url, headers=headers, timeout=15)
    match = re.search(r'data-sitekey=["\']([0-9x][A-Za-z0-9_-]+)["\']', response.text)
    return match.group(1) if match else None

Node.js

const axios = require("axios");

const API_KEY = "YOUR_API_KEY";

async function solveWAFChallenge(url, challengeType) {
  const method =
    challengeType === "js_challenge" ? "turnstile_staging" : "turnstile";
  const sitekey =
    challengeType === "js_challenge" ? "managed" : await extractSitekey(url);

  const submit = await axios.post("https://ocr.captchaai.com/in.php", null, {
    params: {
      key: API_KEY,
      method,
      sitekey,
      pageurl: url,
      json: 1,
    },
  });

  const taskId = submit.data.request;

  for (let i = 0; i < 60; i++) {
    await new Promise((r) => setTimeout(r, 5000));

    const result = await axios.get("https://ocr.captchaai.com/res.php", {
      params: { key: API_KEY, action: "get", id: taskId, json: 1 },
    });

    if (result.data.status === 1) {
      return result.data.request;
    }
  }

  throw new Error("Challenge solve timed out");
}

async function extractSitekey(url) {
  const response = await axios.get(url, {
    headers: {
      "User-Agent": "Mozilla/5.0 Chrome/120.0.0.0",
    },
  });
  const match = response.data.match(/data-sitekey=["']([0-9x][A-Za-z0-9_-]+)["']/);
  return match ? match[1] : null;
}

Mudanças nas regras do WAF e seus efeitos

Os operadores do site ajustam frequentemente as regras do WAF. Essas mudanças afetam a automação:

Mudança Efeito na automação Como detectar
Regra adicionada Novo desafio surge em caminhos que deram certo Monitore alterações de status 503/403
Regra removida O desafio desaparece 200 onde 503 estava antes
Ação escalada (Bloco → gerenciado) Desafio solucionável torna-se bloco difícil 403 em vez de 503
Ação relaxada (Bloco → gerenciado) Bloco difícil torna-se desafio solucionável 503 com página de desafio
Limite alterado (pontuação do bot 30 → 50) Mais solicitações contestadas Maior frequência de desafio
Escopo do caminho alterado Diferentes URLs afetados Novos caminhos retornam desafios

Estratégia de monitoramento

import requests
import time

def monitor_cloudflare_protection(urls, interval=3600):
    """Monitor protection changes across URLs."""
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                      "AppleWebKit/537.36 Chrome/120.0.0.0",
        "Accept": "text/html,*/*;q=0.8",
        "Accept-Language": "en-US,en;q=0.9",
    }

    last_status = {}

    while True:
        for url in urls:
            try:
                response = requests.get(
                    url, headers=headers, timeout=15, allow_redirects=False
                )
                status = response.status_code
                has_challenge = status == 503 or "cf-turnstile" in response.text

                current = {"status": status, "challenge": has_challenge}
                previous = last_status.get(url)

                if previous and current != previous:
                    print(f"[CHANGE] {url}")
                    print(f"  Before: {previous}")
                    print(f"  After:  {current}")

                last_status[url] = current

            except requests.RequestException as e:
                print(f"[ERROR] {url}: {e}")

        time.sleep(interval)

Solução de problemas

Sintoma Provável regra WAF Correção
Desafio apenas em /login Regra baseada em caminho Resolva o desafio para esse caminho
Desafio apenas de IPs de datacenter Pontuação do bot ou regra de reputação de IP Use proxies residenciais ou resolva desafios
O desafio varia de acordo com o país Regra baseada no país Use proxy no país permitido ou resolva
Desafio após N solicitações Regra baseada em taxa Reduza a taxa de solicitação ou resolva cada desafio
Desafie sempre JS (nunca Turnstile) Ação do desafio JS (não gerenciado) Use o método turnstile_staging
403 sem desafio Ação de bloqueio (não solucionável) Alterar IP, cabeçalhos ou padrão de solicitação

Perguntas frequentes

Posso ver quais regras WAF um site usa?

Não. As regras do WAF são privadas do operador do site. Você só pode inferir regras a partir do comportamento – quais caminhos desencadeiam desafios, de quais IPs e que tipo de desafio aparece.

As regras do WAF se aplicam a todos os planos da Cloudflare?

Regras WAF personalizadas estão disponíveis em todos os planos pagos (Pro, Business, Enterprise). Os planos gratuitos têm regras WAF limitadas. No entanto, o Managed Challenge está disponível em todos os planos, incluindo o Gratuito.

As regras do WAF podem desencadear desafios diferentes para caminhos diferentes?

Sim. Cada regra do WAF pode ter uma ação diferente e corresponder a caminhos diferentes. Um site pode usar o Desafio Gerenciado para /login e o Desafio JS para endpoints /api/.

Com que frequência os sites alteram suas regras do WAF?

Isso varia. Os sites de comércio eletrônico costumam ajustar as regras durante os eventos de vendas. Sites preocupados com a segurança podem atualizar as regras semanalmente. A maioria dos sites raramente altera as regras após a configuração inicial.

A resolução de um desafio do WAF afeta solicitações futuras?

Sim. Após a resolução, o cookie cookie_qa_validacao permite que as solicitações subsequentes passem sem contestação por aproximadamente 30 minutos. O cookie está vinculado ao seu IP e User-Agent.


Resumo

As regras WAF da Cloudflare acionam desafios CAPTCHA com base em condições configuráveis: pontuação do bot, país, caminho, cabeçalhos ou taxa. A ação mais comum é o Desafio Gerenciado, que a Cloudflare renderiza de forma adaptativa como desafio invisível, Turnstile ou JS. Resolva isso comCaptchaAIusando o método turnstile ou turnstile_staging dependendo do que é renderizado. Os blocos rígidos (403) das regras WAF não são solucionáveis ​​– em vez disso, altere seu padrão de solicitação ou IP.

Artigos relacionados

Os comentários estão desativados para este artigo.