Технические разборы

Правила Cloudflare WAF, которые вызывают проблемы CAPTCHA

Брандмауэр веб-приложений Cloudflare (WAF) позволяет операторам сайтов создавать правила, которые запускают задачи CAPTCHA на основе определенных атрибутов запроса — IP-адреса, страны, URL-адреса, оценки бота, заголовков или любой комбинации. Понимание того, какие правила вызывают проблемы, поможет вам диагностировать, почему вы видите CAPTCHA, и выбрать правильный подход к ее устранению.


Действия правил WAF, которые создают CAPTCHA

Правила Cloudflare WAF поддерживают несколько действий. Три из них представляют собой решаемые задачи:

действие WAF Что происходит Статус HTTP Метод CaptchaAI
Управляемое соревнование Cloudflare решает: невидимый вызов, Cloudflare Turnstile или JS-задача 503 turnstile
JS-вызов 5-секундная страница с вызовом JavaScript 503 turnstile
Интерактивный вызов Традиционная CAPTCHA (устаревшая, устаревшая) 403 turnstile
Блокировать Жесткий 403, без проблем 403 N/A (неразрешимо)
Позволять Пройти, без проверки 200 PLACEHOLDER_TOKEN
Пропускать Пропустить оставшиеся правила WAF 200 PLACEHOLDER_TOKEN
Бревно Записать событие, никаких действий 200 PLACEHOLDER_TOKEN

Управляемая задача (наиболее распространенная)

Управляемый вызов — это рекомендуемое действие 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 → qa_validation_cookie 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

Правила оценки ботов являются наиболее распространенным триггером для инструментов автоматизации. API-решатели 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-защиты в 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

Из идентификатора Cloudflare Ray

Каждый ответ Cloudflare включает заголовок cf-ray. Операторы сайта могут использовать этот идентификатор Ray ID на панели управления Cloudflare (Безопасность > События), чтобы точно узнать, какое правило сработало и какое действие было предпринято.


Решение проблем, вызванных WAF

Стратегия, основанная на типе задачи

import requests
import time

API_KEY = "YOUR_API_KEY"

def solve_turnstile(url, challenge_type):
    """Solve страница Cloudflare-защиты в 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"
        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" : "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 (никогда Cloudflare Turnstile) Действие JS Challenge (не управляемое) Используйте метод turnstile.
403 без проблем Действие блока (не решаемое) Изменить IP, заголовки или шаблон запроса

Часто задаваемые вопросы

Могу ли я увидеть, какие правила WAF использует сайт?

Нет. Правила WAF являются конфиденциальными для оператора сайта. Вы можете вывести правила только из поведения — какие пути вызывают проблемы, с каких IP-адресов и какой тип проблемы появляется.

Применяются ли правила WAF ко всем планам Cloudflare?

Пользовательские правила WAF доступны во всех платных планах (Pro, Business, Enterprise). Бесплатные планы имеют ограниченные правила WAF. Однако Managed Challenge доступен на всех планах, включая бесплатный.

Могут ли правила WAF вызывать разные проблемы для разных путей?

Да. Каждое правило WAF может иметь разное действие и соответствовать разным путям. Сайт может использовать Managed Challenge для /login и JS Challenge для конечных точек /api/.

Как часто сайты меняют свои правила WAF?

Это варьируется. Сайты электронной коммерции часто корректируют правила во время распродаж. Сайты, заботящиеся о безопасности, могут обновлять правила еженедельно. Большинство сайтов редко меняют правила после первоначальной настройки.

Влияет ли решение задачи WAF на будущие запросы?

Да. После решения файл cookie qa_validation_cookie позволяет последующим запросам проходить без проблем в течение примерно 30 минут. Файл cookie привязан к вашему IP-адресу и пользовательскому агенту.


Краткое содержание

Правила Cloudflare WAF запускают испытания CAPTCHA на основе настраиваемых условий: оценка бота, страна, путь, заголовки или скорость. Наиболее распространенным действием является управляемый вызов, который Cloudflare адаптивно отображает как невидимый, Cloudflare Turnstile или вызов JS. Решите их с помощьюCaptchaAIиспользуя метод turnstile или turnstile в зависимости от того, что визуализируется. Жесткие блоки (403) из правил WAF неразрешимы — вместо этого измените шаблон запроса или IP-адрес.

Похожие статьи

Комментарии для этой статьи отключены.