حين يتوقف سكربت الأتمتة عند صفحة "Checking your browser" ويردّ الخادم برمز HTTP 503، فأنت غالبًا أمام وضع "I'm Under Attack Mode" — أو IUAM — من Cloudflare. لا يطلب نقرة ولا صورة، بل يفرض على كل طلب تحدي JavaScript مدته نحو 5 ثوانٍ تعجز عنه عملاء HTTP كـ requests وAxios.
الحل باختصار: نفّذ التحدي داخل بيئة تشغّل JavaScript أو مرّره إلى خدمة حلّ فتحصل على cf_clearance تعيد استخدامه طوال صلاحيته. وفي ما يلي كيف تميّز IUAM عن بقية دفاعات Cloudflare وتعالجه عبر cloudflare_challenge.
سيناريو من السوق: بوت أسعار تحت الهجوم
تخيّل بوت مراقبة أسعار يتابع متجرًا إقليميًا قبيل موسم تخفيضات كالجمعة البيضاء. ترتفع حركة المرور فجأة فيفعّل المتجر وضع الهجوم، فيعود كل طلب برمز 503 وتتوقف الأسعار في أسوأ توقيت. المعالجة الصحيحة ليست زيادة الطلبات بل معالجة التحدي نفسه:
- مرّر كل نطاق محمي عبر
cloudflare_challengeبدل تكرار الطلبات الفاشلة. - احصل على
cf_clearanceواحد لكل IP وواصل القراءة به حتى انتهاء صلاحيته. - تكفي خطة BASIC بسعر 15$ شهريًا مع 5 threads لمراقبة متجر واحد.
ماذا يحدث عند تفعيل وضع الهجوم
بمجرد تفعيل "I'm Under Attack Mode" من لوحة تحكم Cloudflare، تعترض حافة الشبكة كل طلب وتردّ بصفحة تحدٍّ لا تُحلّ إلا داخل متصفح:
Every request → Cloudflare edge
↓
JavaScript challenge page served (HTTP 503)
↓
Browser executes JavaScript challenge (~5 seconds)
↓
Challenge answer submitted automatically
↓
cf_clearance cookie set
↓
Original page loaded with cf_clearance cookie
عناصر صفحة التحدي
تعيد صفحة التحدي رمز HTTP 503، وتحمل داخل شيفرتها الحقول التالية:
| العنصر | الغرض |
|---|---|
jschl_vc |
رمز التحقق الخاص بالتحدي |
pass |
رمز التوقيت — يفرض انتظارًا مدته 5 ثوانٍ |
jschl_answer |
الإجابة المحسوبة عبر JavaScript |
cf_chl_opt |
خيارات التحدي |
ray |
معرّف Cloudflare Ray للطلب |
| "Checking your browser before accessing..." | الرسالة الظاهرة للمستخدم |
وتتميّز صفحة IUAM برمز 503 لا 403، وانتظار إلزامي 5 ثوانٍ، واشتراط تنفيذ JavaScript، وإصدار cf_clearance يسري على النطاق كله لنحو 30 دقيقة.
كيف تميّز IUAM عن دفاعات Cloudflare الأخرى
قبل كتابة منطق المعالجة، حدّد الدفاع الذي تواجهه، فـ IUAM يختلف عن التحدي المُدار وعن 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 challenge (generic)"
if status == 200:
return "No challenge (passed)"
return f"Unknown (status: {status})"
جدول التمييز السريع
| الإشارة | IUAM | التحدي المُدار | Turnstile | حظر WAF |
|---|---|---|---|---|
| رمز HTTP | 503 | 503 | 200 | 403 |
وجود jschl في الجسم |
✅ | ❌ | ❌ | ❌ |
| انتظار 5 ثوانٍ | ✅ | أحيانًا | ❌ | ❌ |
ضبط cf_clearance |
بعد الحل | بعد الحل | ❌ | ❌ |
| صفحة التحدي | صفحة كاملة | صفحة كاملة | العنصر فقط | صفحة خطأ |
| يتطلب JavaScript | ✅ | ✅ | ✅ | ❌ |
ما الذي يجري داخل تحدي الـ JavaScript
الغرض من تحدي IUAM هو التأكد من أن الزائر متصفح حقيقي ينفّذ الشيفرة لا عميل مجرد، ويمرّ بست مراحل حتى إصدار التخليص:
تسلسل التحدي خطوة بخطوة
| المرحلة | ما يجري فيها |
|---|---|
| 1. تقديم الصفحة | صفحة تحدٍّ محمّلة بشيفرة JavaScript مبهمة |
| 2. تنفيذ الشيفرة | حساب على سلاسل الصفحة وقياسات DOM وتوقيت لا يقل عن 4–5 ثوانٍ |
| 3. حساب الإجابة | اشتقاق قيمة عددية من بيانات التحدي |
| 4. إرسال النموذج | إرسال تلقائي حاملًا jschl_vc وpass وjschl_answer |
| 5. التحقق | تتأكد Cloudflare من صحة الإجابة والتزام التوقيت |
| 6. إصدار التخليص | إعادة cf_clearance يتيح الوصول نحو 30 دقيقة |
لماذا تفشل عملاء HTTP
السبب أن عميل HTTP المجرّد يجلب صفحة التحدي لكنه لا يملك محرّك JavaScript لتنفيذها، فيبقى عالقًا عند 503 مهما ضبطت ترويساته:
# 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
معالجة IUAM عبر CaptchaAI
بعد تمييز IUAM، أمامك طريقتان للحصول على cf_clearance حسب طبيعة عملك:
- طريقة
cloudflare_challengeالمباشرة — للطلبات عالية الحجم دون متصفح. - أتمتة المتصفح — للجلسات المستمرة التي تحتاج كوكيز حيّة.
الطريقة الأولى: 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 cf_clearance cookie or token
# The response contains the clearance data needed to access the site
الطريقة الثانية: أتمتة متصفح بلا واجهة
للجلسات المستمرة، ادمج متصفحًا بلا واجهة لاستخراج الكوكيز بعد التحدي:
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()
cf_clearance = next(
(c["value"] for c in cookies if c["name"] == "cf_clearance"), None
)
if cf_clearance:
print(f"cf_clearance obtained: {cf_clearance[: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
التدفق نفسه متاح خارج Python عبر Axios:
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)));
إدارة ملف cf_clearance وإطالة عمر الجلسة
ملف cf_clearance هو الناتج الفعلي لحل تحدي IUAM، وإدارته الجيدة تحدد كفاءة الأتمتة على المدى الطويل:
| الخاصية | القيمة |
|---|---|
| اسم الملف | cf_clearance |
| مدة الصلاحية | نحو 30 دقيقة، قابلة للضبط من جانب الموقع |
| النطاق | على مستوى النطاق بالكامل |
| مرتبط بـ | عنوان IP + سلسلة User-Agent |
| قابل لإعادة الاستخدام | نعم، طوال الصلاحية |
| قابل للنقل | فقط مع نفس IP وUser-Agent |
استراتيجية إدارة الجلسة
الصنف التالي يحفظ الجلسة ويعيد الحل تلقائيًا قبل انتهاء الصلاحية بدل انتظار 503:
import requests
import time
class IUAMSessionManager:
"""Manage cf_clearance 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)
إطالة عمر التخليص
- ثبّت IP وUser-Agent نفسيهما بين الحل والاستخدام.
- جدّد الملف قبل انتهاء صلاحيته لا بعد ظهور الخطأ.
- خصّص
cf_clearanceمنفصلًا لكل IP عند تعدد البروكسيات.
معالجة الأعطال الشائعة
معظم مشكلات IUAM من عدم تطابق IP أو User-Agent أو انتهاء التخليص:
| العَرَض | السبب | الإصلاح |
|---|---|---|
| التحدي يتكرر بلا نهاية | تغيّر IP بعد التخليص | ثبّت IP نفسه للحل والوصول |
رفض cf_clearance |
عدم تطابق User-Agent | استخدم نفس User-Agent في الحل والطلبات |
| استمرار 503 بعد الحل | انتهت صلاحية الملف (>30 دقيقة) | جدّد التخليص قبل انتهائها |
| الصفحة غير متوقعة | الموقع يستخدم التحدي المُدار لا IUAM | انتقل إلى حل Turnstile |
| تعدد صفحات التحدي | الأول IUAM والثاني Turnstile | عالِج الاثنين بالتسلسل |
الأسئلة الشائعة
أكثر ما يسأل عنه المطورون:
لماذا يستمر خطأ 503 رغم ضبط ترويسات الطلب يدويًا؟
لأن IUAM لا يفحص الترويسات فحسب، بل يطلب تنفيذ JavaScript والالتزام بمهلة الـ5 ثوانٍ؛ فعميل HTTP يرسل الترويسات دون تنفيذها فيبقى عند 503. الحل أحد أمرين:
- شغّل التحدي داخل بيئة تنفّذ JavaScript فعليًا.
- أو مرّره إلى
cloudflare_challengeلتحصل علىcf_clearance.
هل تؤثر معالجة IUAM على عدد الـ threads في خطتي على CaptchaAI؟
النموذج قائم على الـ threads المتزامنة لا على عمليات الحل، فلا رسوم لكل عملية ولا سقف يومي:
- كل تحدٍّ قيد المعالجة يشغل thread واحدًا أثناء الحل فقط.
- بمجرد أن يعود
cf_clearanceيتحرر الـ thread لتحدٍّ جديد.
هل يمكن مشاركة cf_clearance بين عدة خوادم وسيطة (بروكسيات)؟
لا. الملف مرتبط بـ IP وسلسلة User-Agent اللذين حُلّ التحدي عبرهما، وأي تغيير يُبطله. عند تعدد البروكسيات، احصل على cf_clearance منفصل لكل IP مع تثبيت User-Agent.
هل معالجة IUAM مسموحة لمواقعي أو لمهام المراقبة المصرّح بها؟
نعم. cloudflare_challenge مصمّمة للاستخدامات المشروعة، ومنها:
- اختبار الجودة على موقع تملكه.
- مراقبة توافر خدمة لك صلاحية الوصول إليها.
- أتمتة تكامل معتمدة ضمن شروط الموقع.
الخلاصة
يفرض وضع الهجوم تحدي JavaScript إلزاميًا، ويردّ برمز 503 مع مهلة حسابية مدتها 5 ثوانٍ. عالِج تحدياته عبر حلّ Cloudflare Challenge من CaptchaAI، ثم استخدم cf_clearance داخل نافذة الـ30 دقيقة. وخطوات المعالجة ثلاث:
- ميّز IUAM عبر رمز 503 ووجود
jschlفي الصفحة. - مرّر الصفحة إلى
cloudflare_challengeواحصل علىcf_clearance. - طابِق IP وUser-Agent بين الحل والاستخدام.
مقالات ذات صلة
- الفرق بين Cloudflare Challenge وTurnstile وكيفية اكتشاف كل منهما
- آلية عمل Cloudflare Challenge خطوة بخطوة
- جولة في تدفق جلسة Cloudflare Challenge