Trang trả về lỗi 503 kèm dòng "Checking your browser before accessing..." dù server đích vẫn hoạt động bình thường? Đó gần như chắc chắn là Cloudflare "I'm Under Attack Mode" (IUAM) — lớp phòng thủ DDoS mạnh nhất của Cloudflare, bắt mọi khách truy cập (kể cả request gọi thẳng vào API) chạy xong một thử thách JavaScript ~5 giây trước khi nhận nội dung thật. Site operator có thể bật thủ công khi đang bị tấn công hoặc để mặc định vĩnh viễn. Với client HTTP thuần (requests, axios, cURL…) không có engine JavaScript, thử thách này không thể vượt qua bằng retry hay đổi header — cần một bộ giải chuyên dụng.
Cơ chế hoạt động của IUAM
Khi site operator bật "I'm Under Attack Mode", luồng xử lý mỗi request trở thành:
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
Trang thử thách trả về HTTP 503 kèm các tham số sau:
| Yếu tố | Vai trò |
|---|---|
jschl_vc |
Mã xác minh thử thách |
pass |
Token thời gian — ép client phải chờ đủ ~5 giây |
jschl_answer |
Kết quả tính toán bằng JavaScript |
cf_chl_opt |
Tham số cấu hình thử thách |
ray |
Cloudflare Ray ID gắn với request |
| "Checking your browser before accessing..." | Thông báo hiển thị cho người dùng thật |
Ba đặc điểm nhận ra IUAM ngay: mã trạng thái luôn là HTTP 503 (403 là bị chặn hẳn), có chờ bắt buộc ~5 giây trước khi submit, và bắt buộc thực thi JavaScript vì client HTTP đơn thuần không tính được jschl_answer. Cookie xác thực có hiệu lực toàn miền ~30 phút, áp dụng cho mọi trang, kể cả route API không render HTML.
Đừng nhầm mọi lỗi 503 của Cloudflare là IUAM. Managed Challenge, Turnstile và WAF block trả về tín hiệu khác nhau — nhầm lẫn giữa chúng là lý do phổ biến khiến script "giải xong vẫn không vào được trang".
Nhận diện đúng lớp bảo vệ và vì sao HTTP client thường thất bại
Phân biệt IUAM với Managed Challenge, Turnstile, WAF block
Đoạn code dưới đây soi từng tín hiệu HTTP để phân loại chính xác trước khi chọn phương pháp giải:
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 challenge (generic)"
if status == 200:
return "No challenge (passed)"
return f"Unknown (status: {status})"
| Tín hiệu | IUAM | Managed Challenge | Turnstile | WAF Block |
|---|---|---|---|---|
| HTTP status | 503 | 503 | 200 | 403 |
jschl xuất hiện trong body |
✅ | ❌ | ❌ | ❌ |
| Chờ 5 giây | ✅ | Đôi khi | ❌ | ❌ |
Set cookie qa_session_cookie |
Sau khi giải | Sau khi giải | ❌ | ❌ |
| Kiểu trang thử thách | Toàn trang | Toàn trang | Chỉ widget | Trang lỗi |
| Cần JavaScript | ✅ | ✅ | ✅ | ❌ |
Trang trả về widget Turnstile thay vì thử thách toàn trang? Đó là Managed Challenge, không phải IUAM — dùng phương pháp giải Turnstile thay vì cloudflare_challenge.
Vì sao HTTP client thường (không phải trình duyệt) luôn thất bại
Thử thách JavaScript của IUAM chứng minh khách truy cập có một trình duyệt thật: Cloudflare trả về trang thử thách với JavaScript bị obfuscate, JavaScript tính toán trên chuỗi lấy từ trang và đo DOM trong tối thiểu 4–5 giây, kết quả jschl_answer được form tự submit lên Cloudflare kèm jschl_vc và pass, Cloudflare xác thực cả kết quả lẫn thời gian, rồi trả về cookie qa_session_cookie nếu hợp lệ.
requests, axios, cURL hay bất kỳ HTTP client nào không có engine JavaScript đều dừng lại ngay từ bước đầu — chúng nhận trang thử thách nhưng không có cách nào chạy JavaScript để tính ra jschl_answer:
# 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
Đây cũng là lý do thêm header giả hay đổi User-Agent không giải quyết được gì — vấn đề nằm ở việc thiếu runtime JavaScript, không phải ở request.
Giải IUAM bằng CaptchaAI
Tình huống thường gặp: đội QA outsourcing tại TP.HCM chạy script theo dõi giá đối thủ trên các sàn thương mại điện tử. Trang đích bật IUAM đúng đợt khuyến mãi, request bắt đầu trả về 503 — client HTTP thuần không tự vượt qua được, cần bộ giải xử lý thay phần JavaScript.
Cách 1: Bộ giải Cloudflare Challenge (khuyến nghị)
Phương thức cloudflare_challenge của CaptchaAI giải trực tiếp IUAM, không cần dựng trình duyệt:
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
Chỉ ba bước:
- Gửi task tới
in.phpvớimethod=cloudflare_challenge. - Polling
res.phpmỗi 5 giây tới khistatusbằng 1. - Dùng dữ liệu clearance trả về để tiếp tục request — không cần Selenium, không cần trình duyệt.
Cách 2: Kết hợp trình duyệt headless với CaptchaAI
Cho phiên cần duy trì lâu hơn một request, kết hợp trình duyệt headless với CaptchaAI để vừa giữ session vừa xử lý thử thách khi cần:
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("")
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()
Trình duyệt tự vượt qua thử thách khi chạy headed; nếu chạy headless và không tự pass, phần fallback gọi CaptchaAI giải thay. Sau khi có cookie clearance, các request tiếp theo dùng requests.Session() bình thường, không cần chạy lại trình duyệt.
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)));
Cùng logic gửi/polling như bản Python, chỉ khác cú pháp async/await — cả hai gọi chung một cặp endpoint in.php/res.php.
Quản lý cookie cf_clearance sau khi giải
Cookie cf_clearance (qa_session_cookie trong code ở trên) là kết quả chính của việc giải IUAM — có nó, request tiếp theo trong ~30 phút không cần giải lại:
| Thuộc tính | Giá trị |
|---|---|
| Tên cookie | cf_clearance |
| Thời hạn | ~30 phút (site operator có thể cấu hình khác) |
| Phạm vi | Toàn miền (domain-wide) |
| Gắn với | Địa chỉ IP + User-Agent dùng lúc giải |
| Tái sử dụng | Được, trong suốt thời hạn |
| Chuyển sang máy/IP khác | Không — chỉ hợp lệ với đúng IP + User-Agent ban đầu |
Với workload chạy liên tục, nên tự quản lý thời điểm hết hạn thay vì đợi 503 quay lại:
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)
needs_refresh() chủ động giải lại trước khi cookie hết hạn 60 giây, thay vì đợi request thất bại rồi mới retry.
Xử lý sự cố thường gặp
| Triệu chứng | Nguyên nhân | Cách xử lý |
|---|---|---|
| Vòng lặp thử thách vô tận | IP thay đổi sau khi đã có cookie clearance | Dùng cùng một IP xuyên suốt cả bước giải lẫn bước request |
Cookie cf_clearance bị từ chối |
User-Agent lúc request khác User-Agent lúc giải | Dùng đúng một User-Agent cho cả hai bước |
| Vẫn 503 dù đã giải | Cookie hết hạn (>30 phút) | Làm mới cookie trước khi hết hạn, không đợi lỗi mới giải lại |
| Trang thử thách trông khác dự kiến | Trang dùng Managed Challenge, không phải IUAM | Chuyển sang phương pháp giải Turnstile |
| Gặp liên tiếp hai trang thử thách | Thử thách đầu là IUAM, thử thách sau là Turnstile | Giải tuần tự cả hai, đừng bỏ qua trang thứ hai |
Câu hỏi thường gặp
IUAM khác gì với Managed Challenge của Cloudflare?
IUAM thách thức mọi khách truy cập vô điều kiện, luôn trả về 503 kèm thử thách JavaScript toàn trang. Managed Challenge chỉ thách thức lưu lượng đáng ngờ và có thể trả về widget Turnstile thay vì trang JS đầy đủ. Cách phân biệt nhanh nhất: có jschl trong HTML hay không.
Làm sao biết trang có đang bật IUAM mà không cần thử request thật?
Không có API công khai để hỏi Cloudflare trước. Cách thực tế là gửi một request thử: nếu nhận HTTP 503 kèm jschl trong body, đó là IUAM (dùng hàm identify_cloudflare_protection() ở phần trên để tự động hóa việc này trong pipeline scraping/QA).
Giải IUAM bằng CaptchaAI tốn bao nhiêu?
CaptchaAI tính phí theo thread song song, không theo số lần giải — BASIC ($15/tháng, 5 thread) đủ cho khối lượng nhỏ, số lần giải mỗi thread không giới hạn. Khối lượng lớn hơn thì cần nhiều thread hơn để giải song song nhiều IUAM cùng lúc.
Đã có cookie clearance nhưng API vẫn trả về 503, vì sao?
Ba lý do thường gặp: IP request khác IP lúc giải, User-Agent không khớp, hoặc cookie đã quá 30 phút. Kiểm tra theo thứ tự này trước khi nghi ngờ bộ giải bị lỗi.
IUAM có ảnh hưởng tới các endpoint API gọi trực tiếp, không qua trình duyệt không?
Có. IUAM áp dụng cho toàn domain, kể cả route API không render HTML — đây là lý do request gọi thẳng API từ script vẫn nhận 503 dù chưa từng mở trình duyệt.
Tóm tắt
IUAM buộc mọi khách truy cập vượt qua thử thách JavaScript bắt buộc, trả về HTTP 503 kèm tính toán ~5 giây. Nhận diện đúng IUAM (phân biệt Managed Challenge, Turnstile, WAF block), giải bằng Cloudflare Challenge solver của CaptchaAI, rồi dùng cookie cf_clearance cho request tiếp theo trong cửa sổ 30 phút — luôn khớp IP và User-Agent giữa bước giải và bước dùng.