Explainers

Как справиться с Cloudflare в режиме атаки

Если сайт вдруг отвечает HTTP 503, держит паузу пять секунд и показывает «Checking your browser» — почти наверняка включён IUAM, режим Cloudflare «I'm Under Attack Mode»: самая жёсткая из защит от DDoS.

Оператор включает её вручную во время атаки либо держит постоянно на чувствительных доменах — страницах входа, оформления заказа, API. Для requests, curl и большинства парсеров это тупик: код не умеет исполнять JavaScript, а без этого проверка не проходит ни при каком числе повторов.


Как распознать IUAM

Когда оператор включает «Режим атаки» в панели Cloudflare, поток запроса выглядит так:

Every request → Cloudflare edge
    ↓
JavaScript challenge page served (HTTP 503)
    ↓
Browser executes JavaScript challenge (~5 seconds)
    ↓
Challenge answer submitted automatically
    ↓
qa_validation_cookie cookie set
    ↓
Original page loaded with qa_validation_cookie cookie

Ключевые признаки IUAM

  • HTTP-статус 503 (не 403 — это важное отличие от блокировки WAF).
  • Обязательная 5-секундная пауза перед отправкой ответа.
  • Нужен реальный JavaScript-движок — обычные HTTP-клиенты здесь бессильны.
  • Cookie qa_validation_cookie — действует около 30 минут и разрешает последующие запросы.
  • Захватывает весь домен целиком — проверка появляется на каждой странице, включая API.

Что возвращает страница проверки

Ответ приходит с кодом HTTP 503 и содержит:

Элемент Назначение
jschl_vc Код подтверждения проверки
pass Токен времени (обеспечивает 5-секундную паузу)
jschl_answer Ответ, вычисленный JavaScript
cf_chl_opt Параметры проверки
ray Идентификатор Cloudflare Ray для запроса
«Проверка браузера перед доступом к...» Сообщение, которое видит пользователь

Пример из практики: QA-стенд под IUAM

Допустим, QA-команда в Алматы или Москве тестирует чекаут интернет-магазина клиента перед сезонной распродажей. Оператор включает IUAM, чтобы отсечь ботовый трафик, — и заодно ломает прогоны на staging-стенде самой команды.

Если в логах прогонов остаются пользовательские данные, сохраняйте только то, что реально нужно для проверки, — вне зависимости от того, работаете вы по 152-ФЗ или по GDPR.

  • Решение то же: запрос к методу turnstile на staging-адрес клиента, а не на боевой прод.
  • Для пары параллельных сценариев хватает тарифа BASIC ($15/мес, 5 потоков, неограниченные решения на поток).
  • При росте нагрузки логичнее перейти на STANDARD ($30/мес, 15 потоков).

IUAM или другая защита Cloudflare?

Прежде чем писать обработчик, стоит понять, с чем вы столкнулись — IUAM, Managed Challenge, Turnstile-виджет и блокировка WAF выглядят по-разному:

import requests

def identify_cloudflare_protection(url):
    """Distinguish IUAM from other Cloudflare protections."""
    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, allow_redirects=False)
    html = response.text
    status = response.status_code

    if status == 503 and "jschl" in html:
        return "IUAM (I'm Under Attack Mode)"

    if status == 503 and "challenge-platform" in html:
        return "Managed Challenge"

    if status == 403 and "cf-ray" in str(response.headers):
        return "Blocked by WAF/Bot Management"

    if "cf-turnstile" in html:
        return "Turnstile widget"

    if "challenges.cloudflare.com" in html:
        return "страница Cloudflare-защиты в staging (generic)"

    if status == 200:
        return "No challenge (passed)"

    return f"Unknown (status: {status})"

Ключевые отличия

  • IUAM — HTTP 503, jschl в теле ответа, обязательная 5-секундная пауза, cookie qa_validation_cookie ставится после решения, JS обязателен.
  • Managed Challenge — тоже 503, но jschl в ответе нет, пауза не гарантирована, JS всё равно нужен.
  • Cloudflare Turnstile — статус 200, виджет встроен в страницу, JS нужен, но без 5-секундной паузы.
  • Блокировка WAF — статус 403, страница ошибки вместо испытания, JS не требуется — отказ окончательный.
  1. Проверьте статус ответа — 503 или 403.
  2. Поищите jschl в теле HTML.
  3. Если статус 200 и на странице есть виджет — это Turnstile, а не IUAM.

Что происходит внутри JS-проверки

Задача IUAM устроена так, чтобы отсечь всё, что не ведёт себя как настоящий браузер:

  1. Cloudflare отдаёт страницу проверки с обфусцированным JavaScript.
  2. Скрипт выполняет вычисления: математические операции над строками со страницы, замеры DOM, выдержку по времени (минимум 4–5 секунд).
  3. Формируется ответ — числовое значение, зависящее от условия задачи.
  4. Форма отправляется автоматически обратно в Cloudflare вместе с jschl_vc, pass и jschl_answer.
  5. Cloudflare сверяет ответ и время выполнения.
  6. Возвращается cookie qa_validation_cookie — доступ открыт примерно на 30 минут.

Почему обычные HTTP-клиенты не проходят проверку

# This will ALWAYS get the challenge page:
import requests
response = requests.get("https://iuam-protected-site.com")
# response.status_code == 503
# response.text contains "Checking your browser..."

# Plain HTTP clients cannot:
# - Execute JavaScript
# - Compute the challenge answer
# - Meet the timing requirement
# - Generate the required cookies

requests и самописные парсеры спотыкаются на первом пункте — исполнить JavaScript им нечем.


Как решить IUAM через API CaptchaAI

Метод 1: прямой запрос к API (рекомендуется)

CaptchaAI принимает такие проверки через метод turnstile — тот же эндпоинт, что и Cloudflare Turnstile:

import requests
import time

API_KEY = "YOUR_API_KEY"
TARGET_URL = "https://iuam-protected-site.com/data"

# Step 1: Submit challenge to CaptchaAI
submit = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "turnstile",
    "sitekey": "managed",
    "pageurl": TARGET_URL,
    "json": 1,
})

task_id = submit.json()["request"]
print(f"Task submitted: {task_id}")

# Step 2: Poll for result
for attempt 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:
        token = result["request"]
        print(f"Challenge solved! Token: {token[:50]}...")
        break
    elif result.get("request") == "ERROR_CAPTCHA_UNSOLVABLE":
        print("Challenge could not be solved")
        break
else:
    print("Timed out waiting for solution")

# Step 3: Use qa_validation_cookie cookie or token
# The response contains the clearance data needed to access the site

sitekey: "managed" — служебное значение для этого типа задачи; реальный sitekey со страницы передавать не нужно.

Метод 2: headless-браузер + CaptchaAI

Для долгоживущих сессий headless-браузер с CaptchaAI удобнее разового запроса к API:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import requests
import time

API_KEY = "YOUR_API_KEY"

# Launch browser
options = webdriver.ChromeOptions()
options.add_argument("--disable-blink-features=AutomationControlled")
driver = webdriver.Chrome(options=options)

# Navigate to IUAM page
driver.get("https://iuam-protected-site.com")

# Wait for challenge page to load
time.sleep(3)

# Check if IUAM challenge is present
if "Checking your browser" in driver.page_source or driver.title == "Just a moment...":
    print("IUAM challenge detected")

    # Option A: Wait for browser to solve natively (if not headless)
    try:
        WebDriverWait(driver, 15).until(
            lambda d: "Checking your browser" not in d.page_source
        )
        print("Challenge passed natively")
    except:
        print("Native solve failed — using CaptchaAI")
        # Submit to CaptchaAI for solving
        # Token submission via JavaScript injection

# After challenge is passed, extract cookies for API use
cookies = driver.get_cookies()
qa_validation_cookie = next(
    (c["value"] for c in cookies if c["name"] == "qa_validation_cookie"), None
)

if qa_validation_cookie:
    print(f"qa_validation_cookie obtained: {qa_validation_cookie[:30]}...")

    # Use cookie with requests library
    session = requests.Session()
    for cookie in cookies:
        session.cookies.set(cookie["name"], cookie["value"])
    session.headers.update({
        "User-Agent": driver.execute_script("return navigator.userAgent"),
    })

    # Now make requests with the clearance cookie
    response = session.get("https://iuam-protected-site.com/api/data")
    print(f"Status: {response.status_code}")

driver.quit()
  • Если проверка проходит нативно — драйвер продолжает работу без обращения к API.
  • Если нет — подключается CaptchaAI, а токен возвращается через тот же эндпоинт turnstile.

Node.js

Тот же сценарий на Node.js, без браузера:

const axios = require("axios");

const API_KEY = "YOUR_API_KEY";
const TARGET_URL = "https://iuam-protected-site.com/data";

async function solveIUAM() {
  // Submit challenge
  const submit = await axios.post("https://ocr.captchaai.com/in.php", null, {
    params: {
      key: API_KEY,
      method: "turnstile",
      sitekey: "managed",
      pageurl: TARGET_URL,
      json: 1,
    },
  });

  const taskId = submit.data.request;
  console.log(`Task submitted: ${taskId}`);

  // Poll for result
  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) {
      console.log("IUAM challenge solved!");
      return result.data.request;
    }
  }

  throw new Error("Timed out");
}

solveIUAM().then((token) => console.log("Token:", token.substring(0, 50)));

qa_validation_cookie — главный результат решения IUAM: он открывает доступ к остальным страницам домена.

  • Название cookie: qa_validation_cookie
  • Срок жизни: ~30 минут (настраивается на стороне сайта)
  • Область действия: весь домен
  • Привязка: IP-адрес + User-Agent
  • Переиспользование: да, пока не истёк срок
  • Передача другому клиенту: только с тем же IP и тем же User-Agent
import requests
import time

class IUAMSessionManager:
    """Manage qa_validation_cookie cookies for IUAM-protected sites."""

    def __init__(self, api_key, target_url, user_agent=None):
        self.api_key = api_key
        self.target_url = target_url
        self.user_agent = user_agent or (
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
            "AppleWebKit/537.36 Chrome/120.0.0.0"
        )
        self.session = requests.Session()
        self.session.headers["User-Agent"] = self.user_agent
        self.clearance_time = 0
        self.clearance_lifetime = 1800  # 30 minutes default

    def needs_refresh(self):
        """Check if clearance cookie needs refreshing."""
        return time.time() - self.clearance_time > self.clearance_lifetime - 60

    def solve_challenge(self):
        """Solve IUAM challenge and update session cookies."""
        submit = requests.post("https://ocr.captchaai.com/in.php", data={
            "key": self.api_key,
            "method": "turnstile",
            "sitekey": "managed",
            "pageurl": self.target_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": self.api_key,
                "action": "get",
                "id": task_id,
                "json": 1,
            }).json()

            if result.get("status") == 1:
                # Apply clearance to session
                self.clearance_time = time.time()
                return result["request"]

        raise TimeoutError("IUAM solve timed out")

    def get(self, url, **kwargs):
        """Make a GET request, solving IUAM if needed."""
        if self.needs_refresh():
            self.solve_challenge()
        return self.session.get(url, **kwargs)

needs_refresh() обновляет cookie за минуту до истечения срока, чтобы не наткнуться на просроченную проверку.


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

По умолчанию — 30 минут, но оператор может настроить срок от 15 минут до 24 часов. Планируйте обновление заранее, а не по факту получения 503.

Сколько стоит автоматическое решение IUAM через CaptchaAI?

  • CaptchaAI тарифицирует по числу одновременных потоков, а не по количеству решённых проверок — на каждом потоке решений сколько угодно за месяц.
  • Для нечастых прогонов хватает BASIC ($15/мес, 5 потоков).
  • При регулярной нагрузке — ADVANCE ($90/мес, 50 потоков).

Как отличить IUAM от обычной блокировки по IP или User-Agent?

Блокировка по IP или UA обычно возвращает 403 без страницы проверки и паузы. IUAM всегда отдаёт 503, показывает страницу проверки и требует JavaScript — 403 без jschl в теле означает, что дело не в IUAM.

Можно ли решать IUAM тем же API-ключом, что и reCAPTCHA или Turnstile?

  • Да, один API-ключ работает для всех методов CaptchaAI.
  • IUAM, reCAPTCHA v2/v3, Cloudflare Turnstile, GeeTest v3 и другие типы решаются тем же ключом — метод передаётся отдельным параметром.

Нет. Cookie привязан к паре IP + User-Agent; при смене любого из параметров сайт потребует проверку заново.


Типичные проблемы при решении IUAM

  • Проверка запускается бесконечно — IP изменился после получения cookie; используйте один и тот же IP для решения и последующих запросов.
  • qa_validation_cookie отклоняется — не совпадает User-Agent; используйте один и тот же User-Agent при решении и в запросах.
  • 503 возвращается снова после решения — cookie истёк (>30 минут); обновляйте cookie заранее, до истечения срока.
  • Страница проверки выглядит иначе, чем ожидалось — на сайте включён Managed Challenge, а не IUAM; переключитесь на решение через метод Turnstile.
  • Проверка появляется дважды подряд — сначала идёт IUAM, затем Turnstile-виджет; решайте оба шага последовательно.

Итоги

Режим «Под атакой» Cloudflare ставит перед каждым посетителем обязательную JS-проверку и отвечает HTTP 503 с 5-секундной паузой.

  • Решайте её через API CaptchaAI.
  • Используйте cookie qa_validation_cookie около 30 минут после решения.
  • Держите IP-адрес и User-Agent одинаковыми при решении и при использовании — это самая частая причина повторных проверок.

Похожие материалы

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