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
- Cloudflare Turnstile em staging vs detecção de catraca
- Como funciona o Cloudflare Turnstile em staging
- Passo a passo do fluxo da sessão Cloudflare Turnstile em staging