Explainers

如何处理攻击模式下的 Cloudflare

脚本请求一个网站,返回永远是 HTTP 503,页面上一行“正在检查您的浏览器”,还卡着大约 5 秒——这基本可以断定,你撞上了 Cloudflare 的“我受到攻击”模式(IUAM,俗称“5 秒盾”)。这是 Cloudflare 最激进的防护等级,运营者遭遇 DDoS 攻击时手动开启,也有站点长期挂着。不管真人还是脚本,都得先跑完一段 JavaScript 计算才能进站,requestsaxioscURL 这类纯 HTTP 客户端做不到,因为它们不执行 JavaScript。

解法:cloudflare_challenge 方法解出挑战,带着 qa_session_cookie 和同一个 IP、User-Agent 继续请求,完整代码见下文。


IUAM(Cloudflare 攻击模式)到底做了什么

打开“我处于攻击模式”开关后,访问链路变成这样:

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

挑战页面里都有什么

IUAM 挑战页返回 HTTP 503,含:

  • jschl_vc——挑战验证码
  • pass——计时令牌,强制 5 秒等待
  • jschl_answer——JavaScript 计算出的答案
  • cf_chl_opt——挑战选项
  • ray——本次请求的 Cloudflare Ray ID
  • “正在检查您的浏览器……”——展示给用户看的提示文案

一眼认出 IUAM 的几个特征

  • 状态码是 503,不是 403
  • 提交答案前必须等满 5 秒,跳不过去
  • 必须执行 JavaScript —— 纯 HTTP 客户端一律失败
  • qa_session_cookie cookie 有效期约 30 分钟,拿到后才能继续访问
  • 域名级生效 —— 站点下每个页面都会被拦下来

怎么判断撞上的是 IUAM,还是别的 Cloudflare 防护

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 验证流程 (generic)"

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

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

四种防护的对照表

信号 IUAM Managed Challenge Turnstile WAF 拦截
HTTP 状态码 503 503 200 403
正文含 jschl
强制 5 秒等待 有时
qa_session_cookie 会写入 解决后 解决后
挑战页范围 整页 整页 仅小部件 错误页
需要执行 JS

那道 JavaScript 挑战到底在算什么

IUAM 的 JavaScript 挑战本质是在验证“这是不是一个真实浏览器”:

挑战的六个步骤

  1. Cloudflare 下发挑战页,代码经过混淆
  2. 浏览器执行计算:对字符串做数学运算、做 DOM 测量、强制计时至少 4-5 秒
  3. 算出答案 —— 基于挑战内容推导出的数值
  4. 自动把 jschl_vcpassjschl_answer 打包成表单提交给 Cloudflare
  5. Cloudflare 校验答案和耗时是否合理
  6. 校验通过后下发 qa_session_cookie 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

用 CaptchaAI 自动解出 IUAM 挑战

举个例子:跨境电商价格监控脚本,目标站点大促期间临时开了 IUAM,请求从 200 变成清一色 503。不用改抓取逻辑,请求前插一次挑战求解,把 qa_session_cookie 带进后续请求即可。

方法一:cloudflare_challenge 方法(推荐)

CaptchaAI 的 cloudflare_challenge 方法直接处理 IUAM 挑战,不需要额外搭浏览器环境:

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": "cloudflare_challenge",
    "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_session_cookie cookie or token
# The response contains the clearance data needed to access the site

cloudflare_challenge 通常在 15 秒内完成识别,成功率较高——具体数值以实测为准。

以下数字基于公开资料与内部观测样本,仅供参考。实际结果会因运行环境、任务量和时间而不同,请在自有环境中测量。

方法二:无头浏览器 + CaptchaAI,适合长会话

需要维持较长会话(不只拿一次 cookie)时,把无头浏览器和 CaptchaAI 组合起来更合适:

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("--no-sandbox")
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_session_cookie = next(
    (c["value"] for c in cookies if c["name"] == "qa_session_cookie"), None
)

if qa_session_cookie:
    print(f"qa_session_cookie obtained: {qa_session_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()

方法一的 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: "cloudflare_challenge",
      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)));

常见故障排查

最常见的几种情况:

  • 挑战循环解不完——IP 变了,解题和访问要用同一个 IP
  • qa_session_cookie 被拒绝——User-Agent 不一致,两边保持一致
  • 解完还是 503——cookie 已过期(超过 30 分钟),提前刷新
  • 挑战页面不一样——实际是 Managed Challenge,换成 Turnstile 方法
  • 撞见多个挑战页——先 IUAM 后 Turnstile,依次解决

解出 IUAM 挑战之后,真正有用的产出就是这个 qa_session_cookie

  • Cookie 名称——qa_session_cookie
  • 有效期——约 30 分钟(站点可自行配置)
  • 作用范围——整个域名
  • 绑定条件——IP 地址 + User-Agent
  • 能否复用——能,在有效期内可反复使用
  • 能否转移——只有 IP + UA 都一致时才行
import requests
import time

class IUAMSessionManager:
    """Manage qa_session_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": "cloudflare_challenge",
            "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)

常见问题

接入时最常被问到:

用 CaptchaAI 解一次 IUAM 大概要多久?

cloudflare_challenge 通常 15 秒内出结果,比图片、网格验证码(通常不到 1 秒)慢,因为要模拟浏览器完成计时计算,轮询间隔建议设在 5 秒左右。

默认约 30 分钟,站点也可配置成 15 分钟到 24 小时,多数用默认值。建议在有效期快到前主动刷新,而不是等失效再补救。

解题时提示 ERROR_CAPTCHA_UNSOLVABLE,是哪里出了问题?

先确认站点真的是 IUAM,而不是已切成 Managed Challenge 或 Turnstile——挑战类型变了自然解不出来。其次检查 pageurl 是否和实际请求地址一致。

Cloudflare 攻击模式是不是一直开着?

不是。多数是运营者遇攻击时临时打开,也有站点长期挂着当额外防护,今天没有不代表明天也没有。

GeeTest、reCAPTCHA 这些验证会不会和 IUAM 出现在同一条链路里?

会。IUAM 只挡在域名入口,站内登录、下单页可能另挂 reCAPTCHA v2/v3、Turnstile 或 GeeTest v3,需按顺序解决:先过 IUAM 拿 qa_session_cookie,再解页面内的验证码。


一句话总结

  • 域名下所有请求清一色 503、页面提示"正在检查您的浏览器",基本可以断定是 Cloudflare 攻击模式(IUAM)
  • CaptchaAI 的 Cloudflare 验证流程 求解器cloudflare_challenge 方法)解出挑战,即可拿到 qa_session_cookie
  • 拿到 cookie 后 30 分钟内可直接复用,但全程要保持同一个 IP 和 User-Agent

相关文章

该文章已禁用评论。