Khi Cloudflare hiển thị một trang thử thách, một luồng mã thông báo phức tạp sẽ bắt đầu - từ các tham số trang ban đầu thông qua thực thi JavaScript đến cookie <staging-session-cookie> cuối cùng. Việc hiểu các tham số này giúp bạn chẩn đoán các lỗi giải quyết, gỡ lỗi các luồng tự động hóa và chọn phương pháp giải quyết phù hợp.
Giải phẫu trang thử thách
Trang thử thách Cloudflare (HTTP 503) chứa một số thành phần chính:
<!DOCTYPE html>
<html>
<head>
<title>Just a moment...</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div id="challenge-stage">
<div id="challenge-body-text">
Checking if the site connection is secure
</div>
<div id="challenge-spinner">
<!-- Loading spinner -->
</div>
</div>
<div id="challenge-form" style="display:none">
<form id="challenge-form" action="/..." method="POST">
<!-- Hidden parameters -->
<input type="hidden" name="md" value="...">
<input type="hidden" name="r" value="...">
</form>
</div>
<script src="/cdn-cgi/challenge-platform/h/g/orchestrate/chl_page/v1?ray=...">
</script>
</body>
</html>
Thông số chính
Trong trang thử thách
| tham số | Tên | Mục đích |
|---|---|---|
ray |
ID tia Cloudflare | Mã định danh yêu cầu duy nhất, liên kết thách thức với yêu cầu ban đầu |
md |
Siêu dữ liệu thử thách | Trạng thái thử thách được mã hóa |
r |
Mã thông báo phản hồi | Câu trả lời được tính toán (điền bằng JavaScript) |
chl_opt |
Tùy chọn thử thách | Cấu hình cho kịch bản thử thách |
cRay |
tia thách thức | Tia phụ để theo dõi thử thách |
cZone |
Khu vực thử thách | ID vùng đám mây |
cUPMDTk |
Dấu thời gian | Thời gian phát hành thử thách |
cHash |
Thử thách băm | Xác thực tính toàn vẹn |
Trong URL tập lệnh thử thách
/cdn-cgi/challenge-platform/h/g/orchestrate/chl_page/v1?ray=ABC123
| thành phần | Ý nghĩa |
|---|---|
/cdn-cgi/challenge-platform/ |
Cơ sở hạ tầng thách thức Cloudflare |
h/g/ |
Phiên bản thử thách/variant |
orchestrate/ |
Điểm cuối điều phối thử thách |
chl_page/v1 |
Phiên bản trang thử thách |
ray=ABC123 |
Yêu cầu liên kết Ray ID |
Trong tải trọng JavaScript
Tập lệnh thử thách tải các tham số bổ sung:
// Extracted from obfuscated challenge script
window._cf_chl_opt = {
cvId: '2', // Challenge version
cType: 'managed', // Challenge type
cNounce: '...', // Cryptographic nonce
cRay: '...', // Challenge Ray ID
cHash: '...', // Challenge hash
cUPMDTk: '...', // Timestamp
cFPWv: 'g', // Fingerprint version
cTTimeMs: '4000', // Minimum wait time (ms)
cTplV: 5, // Template version
cLt: '...', // Challenge lifetime
cRq: {}, // Challenge request data
};
Luồng mã thông báo từ thử thách đến giải phóng mặt bằng
Luồng từng bước
1. CLIENT → CLOUDFLARE EDGE
GET /protected-page
↓
2. CLOUDFLARE → CLIENT
HTTP 503 + Challenge page HTML
Sets: __cf_bm cookie (bot management tracking)
Contains: ray ID, challenge script URL
↓
3. CLIENT (browser)
Loads challenge script from /cdn-cgi/challenge-platform/...
↓
4. CHALLENGE SCRIPT EXECUTES:
a. Collects browser fingerprint:
- Canvas hash
- WebGL renderer
- Screen dimensions
- Installed fonts
- Timezone
- Language
b. Runs proof-of-work:
- Iterates hash computations
- Must find answer matching difficulty
c. Computes timing:
- Enforces minimum wait (cTTimeMs)
- Records actual timing
d. Generates response token:
- Combines fingerprint + PoW answer + timing
- Encrypts with challenge nonce
↓
5. CLIENT → CLOUDFLARE
POST /cdn-cgi/challenge-platform/h/g/flow/ov1/...
Body: { r: "encrypted_response", md: "metadata", ... }
↓
6. CLOUDFLARE validates:
- Proof-of-work answer correct?
- Timing within acceptable range?
- Fingerprint consistent with real browser?
- No replay (nonce check)?
↓
7. CLOUDFLARE → CLIENT
HTTP 200 + Set-Cookie: <staging-session-cookie>=...; path=/; expires=...
+ HTTP redirect to original URL
↓
8. CLIENT → CLOUDFLARE
GET /protected-page
Cookie: <staging-session-cookie>=...
↓
9. CLOUDFLARE → CLIENT
HTTP 200 + Protected content
Dòng thời gian cookie
Request 1: No cookies
→ Challenge page (503)
→ __cf_bm cookie set
Challenge solve:
→ <staging-session-cookie> cookie set
Request 2+: <staging-session-cookie> + __cf_bm
→ Content served (200)
After ~30 mins: <staging-session-cookie> expires
→ Next request triggers new challenge
Cookie thách thức
| bánh quy | Mục đích | Trọn đời | Phạm vi |
|---|---|---|---|
__cf_bm |
Theo dõi phiên quản lý bot | 30 phút | Tên miền |
<staging-session-cookie> |
Bằng chứng giải phóng mặt bằng thách thức | 15 phút - 24 giờ (có thể định cấu hình) | Tên miền |
__cflb |
Mối quan hệ cân bằng tải | Phiên | Tên miền |
_cfuvid |
ID khách truy cập duy nhất | Phiên | Tên miền |
ràng buộc cookie
Cookie <staging-session-cookie> bị ràng buộc với:
- Địa chỉ IP — Phải đến từ cùng một IP đã giải quyết thử thách
- User-Agent — Phải khớp với UA được sử dụng trong thử thách
- Miền — Chỉ hợp lệ cho miền đã phát hành nó
# ❌ FAILS — IP mismatch
# Solve challenge from IP A, then use <staging-session-cookie> from IP B
# ❌ FAILS — UA mismatch
# Solve with Chrome UA, then send requests with Firefox UA
# ✅ WORKS — Same IP + Same UA
session = requests.Session()
session.headers["User-Agent"] = "Mozilla/5.0 ... Chrome/120.0.0.0"
# Use same session for solving and subsequent requests
Trích xuất các tham số thử thách
Python
import re
import requests
def extract_challenge_params(url):
"""Extract Cloudflare challenge page parameters."""
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)
html = response.text
params = {
"status_code": response.status_code,
"cf_ray": response.headers.get("cf-ray", ""),
"is_challenge": response.status_code == 503,
}
if not params["is_challenge"]:
return params
# Extract Ray ID from page
ray_match = re.search(r"ray['\"]?\s*[:=]\s*['\"]([a-f0-9]+)['\"]", html, re.I)
if ray_match:
params["ray_id"] = ray_match.group(1)
# Extract challenge script URL
script_match = re.search(
r'src=["\'](/cdn-cgi/challenge-platform/[^"\']+)["\']', html
)
if script_match:
params["challenge_script"] = script_match.group(1)
# Extract challenge options
opt_match = re.search(r"_cf_chl_opt\s*=\s*\{([^}]+)\}", html)
if opt_match:
opt_text = opt_match.group(1)
# Parse individual options
for key in ["cType", "cRay", "cHash", "cTTimeMs", "cvId", "cFPWv"]:
val_match = re.search(
rf"{key}\s*:\s*['\"]?([^'\"', }}]+)", opt_text
)
if val_match:
params[key] = val_match.group(1)
# Extract form parameters
md_match = re.search(r'name=["\']md["\']\s+value=["\']([^"\']+)["\']', html)
if md_match:
params["md"] = md_match.group(1)
# Extract cookies from response
params["cookies"] = {
name: value
for name, value in response.cookies.items()
}
return params
# Usage
params = extract_challenge_params("https://protected-site.com")
if params["is_challenge"]:
print(f"Challenge type: {params.get('cType', 'unknown')}")
print(f"Ray ID: {params.get('ray_id', params['cf_ray'])}")
print(f"Min wait: {params.get('cTTimeMs', '?')}ms")
print(f"Script: {params.get('challenge_script', 'not found')}")
Node.js
const axios = require("axios");
async function extractChallengeParams(url) {
const response = await axios.get(url, {
headers: {
"User-Agent": "Mozilla/5.0 Chrome/120.0.0.0",
Accept: "text/html,*/*;q=0.8",
},
validateStatus: () => true,
maxRedirects: 0,
});
const html = response.data;
const params = {
statusCode: response.status,
cfRay: response.headers["cf-ray"] || "",
isChallenge: response.status === 503,
};
if (!params.isChallenge) return params;
// Extract challenge script URL
const scriptMatch = html.match(
/src=["'](\/cdn-cgi\/challenge-platform\/[^"']+)["']/
);
if (scriptMatch) params.challengeScript = scriptMatch[1];
// Extract challenge type
const typeMatch = html.match(/cType\s*:\s*['"]?(\w+)/);
if (typeMatch) params.challengeType = typeMatch[1];
// Extract timing
const timeMatch = html.match(/cTTimeMs\s*:\s*['"]?(\d+)/);
if (timeMatch) params.minWaitMs = parseInt(timeMatch[1]);
return params;
}
extractChallengeParams("https://protected-site.com").then(console.log);
Giải quyết bằng CaptchaAI
CaptchaAI xử lý nội bộ toàn bộ luồng mã thông báo - bạn không cần trích xuất các tham số thử thách theo cách thủ công:
import requests
import time
API_KEY = "YOUR_API_KEY"
def solve_cloudflare_challenge(target_url):
"""Solve Cloudflare challenge page — CaptchaAI handles token flow."""
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"]
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")
# CaptchaAI handles the full flow:
# 1. Loads the challenge page
# 2. Executes JavaScript
# 3. Solves proof-of-work
# 4. Returns clearance token/cookies
token = solve_cloudflare_challenge("https://protected-site.com/login")
Gỡ lỗi thử thách thất bại
Điểm thất bại phổ biến
| Điểm thất bại | Triệu chứng | Nguyên nhân gốc rễ |
|---|---|---|
| Trang thử thách không tải | Hết thời gian chờ hoặc phản hồi trống | Sự cố Network/proxy |
| Tập lệnh không thực thi được | Vòng thử thách | Thiếu API JavaScript |
| Bằng chứng công việc không thành công | Con quay vô hạn | Hết thời gian tính toán |
| Phản hồi bị từ chối | Chuyển hướng trở lại thử thách | Vi phạm thời gian hoặc dấu vân tay không khớp |
| Thiếu cookie sau khi giải quyết | Lỗi phân tích phản hồi | |
| 403 theo yêu cầu tiếp theo | IP hoặc UA không khớp |
Danh sách kiểm tra gỡ lỗi
def debug_challenge_flow(url, cf_clearance_cookie=None, user_agent=None):
"""Debug the challenge solve flow step by step."""
ua = user_agent or (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/120.0.0.0"
)
steps = []
# Step 1: Initial request
response = requests.get(
url,
headers={"User-Agent": ua, "Accept": "text/html,*/*;q=0.8"},
timeout=15,
allow_redirects=False,
)
steps.append({
"step": "initial_request",
"status": response.status_code,
"is_challenge": response.status_code == 503,
"cf_ray": response.headers.get("cf-ray", ""),
})
# Step 2: Test with <staging-session-cookie>
if cf_clearance_cookie:
session = requests.Session()
session.cookies.set("<staging-session-cookie>", cf_clearance_cookie)
session.headers["User-Agent"] = ua
response2 = session.get(url, timeout=15, allow_redirects=False)
steps.append({
"step": "with_clearance",
"status": response2.status_code,
"passed": response2.status_code == 200,
})
if response2.status_code != 200:
steps.append({
"step": "diagnosis",
"issue": "<staging-session-cookie> rejected",
"possible_causes": [
"Cookie expired",
"IP address changed",
"User-Agent mismatch",
"Cookie from different domain",
],
})
return steps
Khắc phục sự cố
| Triệu chứng | nguyên nhân | sửa chữa |
|---|---|---|
| Loại thử thách được "quản lý" nhưng giải quyết không thành công | Thử thách yêu cầu Turnstile chứ không phải thử thách JS | Hãy thử phương pháp turnstile thay vì cloudflare_challenge |
| Xoay IP đã thay đổi IP của bạn | Ghim IP cho thời gian tồn tại | |
| Trang "Đợi một chút..." không bao giờ giải quyết được | JavaScript bị chặn hoặc không đúng định dạng | Sử dụng CaptchaAI thay vì giải thủ công |
| Thử thách xuất hiện lại sau mỗi yêu cầu | cf_thông quan không được gửi | Đảm bảo cookie được duy trì trong phiên |
| Thử thách khác nhau trên những con đường khác nhau | Quy tắc WAF trên mỗi đường dẫn | Giải quyết từng đường dẫn riêng biệt |
Câu hỏi thường gặp
Có gì bên trong cookie ?
Đó là mã thông báo được mã hóa chứa bằng chứng giải quyết, hàm băm IP, hàm băm UA và thời gian hết hạn. Bạn không thể giải mã hoặc giả mạo nó - chỉ cạnh của Cloudflare mới có thể xác thực nó.
kéo dài bao lâu?
Người vận hành trang web định cấu hình thời gian tồn tại. Mặc định là 30 phút. Phạm vi là 15 phút đến 24 giờ. Khách hàng doanh nghiệp có thể đặt giá trị tùy chỉnh.
Tôi có thể giải quyết thử thách mà không cần thực thi JavaScript không?
Không. Thử thách này yêu cầu JavaScript để tính toán bằng chứng công việc và dấu vân tay của trình duyệt. CaptchaAI xử lý việc này nội bộ bằng trình duyệt thực.
Điều gì xảy ra nếu ID Ray thay đổi?
Mỗi yêu cầu nhận được một ID Ray mới. Thử thách được liên kết với ID Ray tại thời điểm trang thử thách. Khi
Tôi có thể sử dụng lại trên các miền khác nhau không?
Không.
Tóm tắt
Các trang thử thách của Cloudflare chứa ID Ray, tập lệnh thử thách, đối tượng tùy chọn và tham số biểu mẫu điều khiển luồng mã thông báo bằng chứng công việc. Luồng tạo ra cookie <staging-session-cookie> được liên kết với IP và Tác nhân người dùng, có hiệu lực trong 15 phút đến 24 giờ. VớiCaptchaAI, bạn không cần phải phân tích cú pháp các tham số này theo cách thủ công — bộ giải sẽ xử lý toàn bộ luồng. Để gỡ lỗi, việc hiểu các tham số sẽ giúp xác định vị trí ngắt luồng.
bài viết liên quan
- Cloudflare Challenge Vs Phát hiện cửa quay
- Thử thách tương tác và quản lý Cloudflare
- Cloudflare Turnstile 403 Sau khi sửa mã thông báo