الشروحات المعمقة

قواعد Cloudflare WAF التي تثير تحديات CAPTCHA

يتيح جدار حماية تطبيقات الويب (WAF) الخاص بـ Cloudflare لمشغلي الموقع إنشاء قواعد تؤدي إلى تحديات CAPTCHA بناءً على سمات طلب محددة - عنوان IP، أو البلد، أو مسار URL، أو نقاط الروبوت، أو الرؤوس، أو أي مجموعة. يساعدك فهم القواعد التي تؤدي إلى التحديات في تشخيص سبب ظهور اختبار CAPTCHA واختيار الطريقة الصحيحة للتعامل معه.


إجراءات قاعدة WAF التي تنتج اختبارات CAPTCHA

تدعم قواعد Cloudflare WAF العديد من الإجراءات. ثلاثة منها تمثل تحديات قابلة للحل:

عمل واف ماذا يحدث حالة HTTP طريقة CaptchaAI
** تحدي الإدارة ** تقرر Cloudflare: تحدي غير مرئي، أو Turnstile، أو JS 503 turnstile
تحدي JS صفحة تحدي JavaScript مدتها 5 ثوانٍ 503 cloudflare_challenge
التحدي التفاعلي اختبار CAPTCHA التقليدي (قديم، مهمل) 403 turnstile
حظر هارد 403، لا يوجد تحدي 403 N/A (غير قابل للحل)
السماح تمر، لا الاختيار 200 N/A
تخطي تخطي قواعد WAF المتبقية 200 N/A
السجل سجل الحدث، لا يوجد إجراء 200 N/A

التحدي المُدار (الأكثر شيوعًا)

التحدي المُدار هو الإجراء الموصى به من Cloudflare. ويقرر بشكل تكيفي نوع التحدي لكل زائر:

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 → cf_clearance cookie issued

أنماط قاعدة WAF الشائعة

يقوم مشغلو الموقع بإنشاء قواعد WAF باستخدام لغة التعبير الخاصة بـ Cloudflare. هذه هي الأنماط التي من المرجح أن تؤدي إلى تشغيل اختبارات CAPTCHA لحركة المرور الآلية:

قواعد النتيجة بوت

# 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 درجات على المستوى البشري لأنها تستخدم متصفحات حقيقية.

القواعد المستندة إلى البلد

# 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

القواعد المستندة إلى المسار

# 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

القواعد القائمة على المعدل

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

القواعد المستندة إلى الرأس

# 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

القواعد المركبة

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

تحديد القاعدة التي تم تشغيلها

عندما يظهر اختبار CAPTCHA، يمكنك تحديد قاعدة التشغيل من الاستجابة:

من رؤوس HTTP

import requests

def check_cloudflare_rule_info(url):
    """Extract WAF rule information from Cloudflare challenge 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

من معرف Cloudflare راي

تتضمن كل استجابة من Cloudflare رأس cf-ray. يمكن لمشغلي الموقع استخدام معرف Ray هذا في لوحة معلومات Cloudflare (الأمان > الأحداث) لمعرفة القاعدة التي تم تشغيلها بالضبط والإجراء الذي تم اتخاذه.


حل التحديات الناجمة عن WAF

استراتيجية تعتمد على نوع التحدي

import requests
import time

API_KEY = "YOUR_API_KEY"

def solve_cloudflare_challenge(url, challenge_type):
    """Solve Cloudflare challenge 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

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 وآثارها

يقوم مشغلو الموقع بضبط قواعد WAF بشكل متكرر. تؤثر هذه التغييرات على الأتمتة:

التغيير التأثير على الأتمتة كيفية الكشف
تم اضافة القاعدة يظهر التحدي الجديد على المسارات التي نجحت مراقبة تغييرات حالة 503/403
تم حذف القاعدة يختفي التحدي 200 حيث كان 503 من قبل
تم تصعيد الإجراء (حظر → المُدار) التحدي القابل للحل يصبح كتلة صعبة 403 بدلاً من 503
الاسترخاء في العمل (تم إدارة حظر →) تصبح الكتلة الصلبة تحديًا قابلاً للحل 503 مع صفحة التحدي
تم تغيير الحد الأدنى (نقاط الروبوت 30 → 50) تم الطعن في المزيد من الطلبات زيادة وتيرة التحدي
تم تغيير نطاق المسار عناوين URL المختلفة المتأثرة مسارات جديدة تعيد التحديات

استراتيجية الرصد

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)

استكشاف الأخطاء وإصلاحها

أعراض قاعدة WAF المحتملة إصلاح
التحدي فقط على /login القاعدة القائمة على المسار حل التحدي لهذا المسار
التحدي من عناوين IP لمركز البيانات فقط نتيجة الروبوت أو قاعدة سمعة IP استخدم الوكلاء السكنيين أو قم بحل التحدي
التحدي يختلف حسب البلد القاعدة القائمة على البلد استخدم الوكيل في البلد المسموح به أو قم بحل المشكلة
التحدي بعد طلبات N القاعدة القائمة على المعدل انخفاض معدل الطلب أو حل كل التحدي
التحدي دائمًا JS (أبدا Turnstile) إجراء تحدي JS (غير مُدار) استخدم طريقة cloudflare_challenge
403 بدون تحدي عمل الحظر (غير قابل للحل) تغيير عنوان IP أو الرؤوس أو نمط الطلب

الأسئلة المتداولة

هل يمكنني معرفة قواعد WAF التي يستخدمها الموقع؟

لا، قواعد WAF خاصة بمشغل الموقع. يمكنك فقط استنتاج القواعد من السلوك - أي المسارات تؤدي إلى التحديات، ومن أي عناوين IP، ونوع التحدي الذي يظهر.

هل تنطبق قواعد WAF على جميع خطط Cloudflare؟

تتوفر قواعد WAF المخصصة في جميع الخطط المدفوعة (Pro وBusiness وEnterprise). الخطط المجانية لها قواعد WAF محدودة. ومع ذلك، فإن Managed Challenge متاح في جميع الخطط بما في ذلك الخطط المجانية.

هل يمكن لقواعد WAF أن تثير تحديات مختلفة لمسارات مختلفة؟

نعم. يمكن أن يكون لكل قاعدة WAF إجراء مختلف وتطابق مسارات مختلفة. قد يستخدم أحد المواقع "التحدي المُدار" لـ /login و"JS Challenge" لنقاط نهاية /api/.

كم مرة تقوم المواقع بتغيير قواعد WAF الخاصة بها؟

إنه يختلف. غالبًا ما تقوم مواقع التجارة الإلكترونية بتعديل القواعد أثناء أحداث المبيعات. قد تقوم المواقع المهتمة بالأمان بتحديث القواعد أسبوعيًا. نادرًا ما تغير معظم المواقع القواعد بعد الإعداد الأولي.

هل يؤثر حل تحدي WAF على الطلبات المستقبلية؟

نعم. بعد الحل، يسمح ملف تعريف الارتباط cf_clearance للطلبات اللاحقة بالمرور دون تحدي لمدة 30 دقيقة تقريبًا. يرتبط ملف تعريف الارتباط بعنوان IP الخاص بك ووكيل المستخدم.


ملخص

تؤدي قواعد Cloudflare WAF إلى إطلاق تحديات CAPTCHA بناءً على شروط قابلة للتكوين: درجة الروبوت، أو البلد، أو المسار، أو الرؤوس، أو المعدل. الإجراء الأكثر شيوعًا هو Managed Challenge، والذي يعرضه Cloudflare بشكل تكيفي كتحدي غير مرئي، أو Turnstile، أو JS. حل هذه معCaptchaAIباستخدام طريقة turnstile أو cloudflare_challenge اعتمادًا على ما يتم تقديمه. الكتل الصلبة (403) من قواعد WAF غير قابلة للحل — قم بتغيير نمط الطلب أو عنوان IP الخاص بك بدلاً من ذلك.

مقالات ذات صلة

أدلة ذات صلة

التعليقات غير مفعّلة لهذا المقال.