Dün sorunsuz çalışan bir sayfada otomasyonunuz bugün aniden bir Cloudflare doğrulaması görüyorsa, sebep neredeyse her zaman tektir: isteğiniz bir WAF kuralına takıldı. Cloudflare'in Web Uygulaması Güvenlik Duvarı (WAF), site operatörlerinin şu özelliklere göre CAPTCHA tetikleyen kurallar tanımlamasına izin verir:
- Bot puanı
- Ülke
- URL yolu (
/login,/api/) - HTTP başlıkları
- İstek oranı
Hangi kuralın devreye girdiğini yanıttan okuyabilirseniz, hem neden doğrulama gördüğünüzü teşhis eder hem de doğru çözüm yöntemini seçersiniz.
CAPTCHA üreten WAF eylemleri
Cloudflare WAF kuralları birden fazla eylemi destekler. Bunlardan yalnızca üçü çözülebilir bir doğrulama önünüze koyar; geri kalanı isteği ya geçirir ya da engeller.
| WAF eylemi | Ne olur | HTTP durumu | CaptchaAI yöntemi |
|---|---|---|---|
| Managed Challenge | Cloudflare karar verir: görünmez geçiş, Turnstile ya da JS doğrulaması | 503 | turnstile |
| JS Challenge | 5 saniyelik JavaScript doğrulama sayfası | 503 | cloudflare_challenge |
| Interactive Challenge | Klasik CAPTCHA (eski, kullanımdan kaldırıldı) | 403 | turnstile |
| Block | Sert 403, doğrulama yok | 403 | Yok (çözülemez) |
| Allow | İstek geçer, kontrol yok | 200 | Yok |
| Skip | Kalan WAF kurallarını uygulamaz | 200 | Yok |
| Log | Olayı kaydeder, eylem yok | 200 | Yok |
Managed Challenge nasıl karar verir
Managed Challenge, en sık gördüğünüz eylemdir. Türü ziyaretçi başına uyarlanabilir seçer:
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 → qa_session_cookie cookie issued
Aynı kural düşük riskte hiç görünmezken yüksek riskte tam JavaScript sayfası açabilir; "bazen çözüm çıkıyor, bazen çıkmıyor" davranışı bu yüzden normaldir.
Otomasyonu en çok tetikleyen WAF kural kalıpları
Kurallar Cloudflare'in ifade diliyle yazılır. En sık karşılaşacağınız kalıplar altı gruba ayrılır. Bot puanı kuralları, otomasyon araçları için en yaygın tetikleyicidir:
# 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
CaptchaAI'nin API çözücüleri gerçek tarayıcılar kullandığından insan seviyesinde puanlar alır. Ülke bazlı kurallar trafiği coğrafyaya göre süzer:
# 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
Yol tabanlı kurallar belirli sayfaları, çoğunlukla oturum ve API uç noktalarını hedefler:
# 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
Orana dayalı kurallar, kısa sürede yükselen istek hacmini yakalar:
# Challenge after high request rate
(cf.threat_score gt 10 and http.request.uri.path contains "/search")
→ Action: Managed Challenge
Başlık tabanlı kurallar, isteğin kimliğine bakar:
# 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
Eksik bir Accept-Language başlığı veya python/curl içeren bir User-Agent tek başına doğrulama tetikleyebilir. Son olarak bileşik kurallar birden çok koşulu birleştirir:
# Multiple conditions
(cf.bot_management.score lt 30
and http.request.uri.path contains "/api/"
and ip.geoip.country ne "US")
→ Action: JS Challenge
Hangi kuralın tetiklendiğini yanıttan okuma
Bir doğrulama çıktığında, tetikleyen kuralı iki sinyalden okursunuz: durum kodu ve gövde imzaları.
HTTP başlıklarından
import requests
def check_cloudflare_rule_info(url):
"""Extract WAF rule information from Cloudflare doğrulama akışı 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
Durum kodu ile gövdedeki imzalar (jschl, challenge-platform, cf-turnstile) birlikte doğrulama türünü ve seçeceğiniz yöntemi belirler.
cf-ray ID'sinden
Her Cloudflare yanıtı bir cf-ray başlığı taşır. Site operatörü bu Ray ID'yi panelde (Security > Events) arayarak hangi kuralın tetiklendiğini görebilir. Sizin tarafınızda cf-ray, yanıtın Cloudflare'den geldiğini doğrular.
Hızlı sorun giderme tablosu
Belirtiden olası kuralı ve doğru yanıtı eşleştirin:
| Belirti | Olası WAF kuralı | Çözüm |
|---|---|---|
Doğrulama yalnızca /login'de çıkıyor |
Yol tabanlı kural | O yol için doğrulamayı çözün |
| Yalnızca veri merkezi IP'lerinden doğrulama | Bot puanı veya IP itibar kuralı | Kendi sunucu altyapınızı gözden geçirin veya doğrulamayı çözün |
| Doğrulama ülkeye göre değişiyor | Ülke bazlı kural | İzin verilen ülkede proxy kullanın veya doğrulamayı çözün |
| N istekten sonra doğrulama | Orana dayalı kural | İstek oranını düşürün veya her doğrulamayı çözün |
| Her zaman JS doğrulaması (hiç Turnstile yok) | JS Challenge eylemi (Managed değil) | cloudflare_challenge yöntemini kullanın |
| Doğrulama olmadan 403 | Block eylemi (çözülemez) | IP'yi, başlıkları veya istek desenini değiştirin |
WAF doğrulamalarını CaptchaAI ile çözme
Çözüm tek bir mantığa iner: Managed Challenge tipik olarak Turnstile olarak render edilir (turnstile), saf JS doğrulaması ise cloudflare_challenge ile çözülür. Her ikisi de CaptchaAI'de tam desteklenen (GA) türlerdir.
Python
import requests
import time
API_KEY = "YOUR_API_KEY"
def solve_cloudflare_challenge(url, challenge_type):
"""Solve Cloudflare doğrulama akışı 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 = "cloudflare_challenge"
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
Akış standart CaptchaAI desenidir: görevi in.php'ye gönderin, sonucu res.php ile sorgulayın, dönen token'ı isteğe ekleyin.
Node.js
const axios = require("axios");
const API_KEY = "YOUR_API_KEY";
async function solveWAFChallenge(url, challengeType) {
const method =
challengeType === "js_challenge" ? "cloudflare_challenge" : "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;
}
WAF kuralları değişince ne olur
Operatörler kuralları sık sık ayarlar ve bu değişiklikler otomasyonunuzu doğrudan etkiler.
| Değişiklik | Otomasyona etkisi | Nasıl tespit edilir |
|---|---|---|
| Kural eklendi | Çalışan yollarda yeni doğrulama çıkar | 503/403 durum değişikliklerini izleyin |
| Kural kaldırıldı | Doğrulama ortadan kalkar | Önceden 503 olan yerde artık 200 |
| Eylem sertleşti (Managed → Block) | Çözülebilir doğrulama sert bloka döner | 503 yerine 403 |
| Eylem yumuşadı (Block → Managed) | Sert blok çözülebilir doğrulamaya döner | Doğrulama sayfasıyla 503 |
| Eşik değişti (bot puanı 30 → 50) | Daha fazla istek doğrulamaya takılır | Artan doğrulama sıklığı |
| Yol kapsamı değişti | Farklı URL'ler etkilenir | Yeni yollar doğrulamayla döner |
Yolları periyodik sorgulayıp durum kodundaki değişimleri yakalamak, kural değişikliğini fark etmenin en pratik yoludur.
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)
Türkiye'den bir senaryo: ödeme akışı QA testi
Bir e-ticaret ekibinin staging.example.com/qa-checkout ödeme adımını otomatik regresyon testleriyle doğruladığını varsayalım. Staging ortamı canlıyla aynı Cloudflare yapılandırmasını kullandığından, test botu /api/ çağrılarında Managed Challenge alır. İki nokta öne çıkar:
- KVKK uyumu: Test verileriniz gerçek kişisel veri içeriyorsa KVKK kapsamına girer — akışı izinsiz kazıma değil, yetkili bir QA süreci olarak konumlandırın.
- Maliyet öngörülebilirliği: CaptchaAI thread bazlı faturalandırır; TL kuru dalgalansa da aylık USD fiyatınız sabittir. BASIC ($15/ay, 5 thread) küçük bir QA paketine yeter.
Sık sorulan sorular
503 mü 403 mü aldığımı anlamak neden önemli?
Çünkü çözülebilirliği belirler. 503 genellikle çözülebilir bir doğrulamadır (Managed veya JS Challenge). Doğrulama sayfası olmadan gelen 403 ise Block eylemidir ve çözülemez.
CaptchaAI hangi Cloudflare doğrulama türlerini çözer?
Cloudflare Turnstile için turnstile, JavaScript tabanlı Cloudflare doğrulama akışı için cloudflare_challenge yöntemini kullanın. İkisi de tam desteklenen türlerdir.
Managed Challenge her zaman Turnstile mı gösterir?
Hayır. Managed Challenge ziyaretçi riskine göre uyarlanır: düşük riskte görünmez geçer, orta riskte Turnstile widget'ı çıkarır, yüksek riskte tam JavaScript sayfası açar.
Doğrulamayı çözdükten sonra çerez ne kadar geçerli olur?
Çözümün ardından qa_session_cookie çerezi, sonraki isteklerin yaklaşık 30 dakika yeniden doğrulama olmadan geçmesine izin verir. Çerez IP'nize ve User-Agent'ınıza bağlıdır.
Cloudflare CAPTCHA otomasyonu KVKK açısından sorun yaratır mı?
Asıl mesele doğrulamayı çözmek değil, topladığınız veridir. Gerçek kişisel veri işliyorsanız KVKK yükümlülükleri devreye girer; CaptchaAI'yi yetkili QA akışları içinde konumlandırın.
Özet
Cloudflare WAF kuralları; bot puanı, ülke, yol, başlık veya istek oranına göre CAPTCHA doğrulaması tetikler. En sık karşılaşacağınız eylem, görünmez geçiş, Turnstile ya da JS doğrulaması olarak uyarlanan Managed Challenge'dır. Tetikleyici kuralı yanıt kodu ve gövde imzalarından okuyun, render edilen türe göre CaptchaAI ile turnstile veya cloudflare_challenge yöntemini seçin. Sert bloklar (403) çözülemez; istek deseninizi veya IP'nizi değiştirin.