El "Modo Estoy bajo ataque" (IUAM) de Cloudflare es una defensa DDoS que obliga a cada visitante a realizar un desafío de JavaScript de 5 segundos antes de acceder al sitio. Es el modo de protección más agresivo de Cloudflare, activado manualmente por los operadores del sitio durante los ataques o habilitado permanentemente en sitios de alto riesgo. Para el acceso automatizado, IUAM crea un desafío de JavaScript obligatorio que los clientes HTTP tradicionales no pueden superar.
¿Qué hace IUAM?
Cuando un operador de sitio habilita "Estoy bajo modo de ataque" en el panel de 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
La página del desafío IUAM
La página de desafío devuelve HTTP 503 y contiene:
| Elemento | Propósito |
|---|---|
jschl_vc |
Código de verificación de desafío |
pass |
Token de tiempo (impone una espera de 5 segundos) |
jschl_answer |
respuesta calculada por JavaScript |
cf_chl_opt |
Opciones de desafío |
ray |
ID de Cloudflare Ray para la solicitud |
| "Comprueba tu navegador antes de acceder..." | Mensaje visible para los usuarios. |
Características clave
- HTTP 503 código de estado (NO 403)
- Espera obligatoria de 5 segundos antes de enviar el desafío
- Se requiere ejecución de JavaScript: los clientes HTTP simples fallan
- cookie qa_validation_cookie: válida durante ~30 minutos, permite solicitudes posteriores
- Todo el dominio: cada página del dominio muestra el desafío
Identificar IUAM frente a otras protecciones de Cloudflare
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})"
Tabla de detección
| Señal | IUAM | Managed Challenge | Turnstile | Bloque WAF |
|---|---|---|---|---|
| Estado HTTP | 503 | 503 | 200 | 403 |
jschl en el cuerpo |
✅ | ❌ | ❌ | ❌ |
| Espera de 5 segundos | ✅ | A veces | ❌ | ❌ |
qa_validation_cookie establecida |
Tras resolver | Tras resolver | ❌ | ❌ |
| Página de challenge | Página completa | Página completa | Solo widget | Página de error |
| Requiere JS | ✅ | ✅ | ✅ | ❌ |
Cómo funciona el desafío de JavaScript
El desafío JavaScript de IUAM está diseñado para verificar que el visitante tiene un navegador real:
Flujo de desafío
- Cloudflare ofrece una página de desafío con JavaScript ofuscado
- JavaScript realiza cálculos: - Operaciones matemáticas sobre cadenas de la página. - Medidas DOM - Aplicación del tiempo (mínimo 4-5 segundos)
- Respuesta calculada: un valor numérico basado en el desafío
- Formulario enviado automáticamente a Cloudflare con
jschl_vc,passyjschl_answer - Cloudflare valida la respuesta y el momento
- Cookie
qa_validation_cookiedevuelta: permite el acceso durante ~30 minutos
Por qué fallan los clientes 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
Resolviendo IUAM con CaptchaAI
Método 1: solucionador Cloudflare Challenge (recomendado)
El método cloudflare_challenge de CaptchaAI maneja los desafíos IUAM directamente:
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_validation_cookie cookie or token
# The response contains the clearance data needed to access the site
Método 2: automatización del navegador con CaptchaAI
Para sesiones persistentes, combine un navegador sin cabeza con 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()
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()
Node.js
// 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)));
---
## Gestión de cookies qa_validation_cookie
La cookie `qa_validation_cookie` es el resultado clave para resolver un desafío IUAM:
| Propiedad | Valor |
|----------|-------|
| **Nombre de la cookie** | `qa_validation_cookie` |
| **Vida útil** | ~30 minutos (configurable en el sitio) |
| **Alcance** | Todo el dominio |
| **Atado a** | Dirección IP + User-Agent |
| **Reutilizable** | Sí, durante toda la vida útil |
| **Transferible** | Solo con la misma IP + UA |
### Estrategia de gestión de cookies
```python
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": "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)
Solución de problemas
| Problema | Causa | Solución |
|---|---|---|
| El challenge se repite sin cesar | La IP cambió tras obtener la autorización | Usa una IP coherente para resolver y acceder |
| qa_validation_cookie rechazado | User-Agent no coincide | Usa el mismo User-Agent al resolver y al solicitar |
| 503 persiste tras resolver | Cookie caducada (>30 min) | Actualiza la autorización antes de que expire |
| Página de challenge diferente a la esperada | El sitio usa Managed Challenge, no IUAM | Cambia al método de resolución de Turnstile |
| Múltiples páginas de challenge | El primer challenge es IUAM, el segundo es Turnstile | Resuelve ambos secuencialmente |
Preguntas frecuentes
¿Cuánto dura qa_validation_cookie?
El valor predeterminado es 30 minutos, pero los operadores del sitio pueden configurarlo entre 15 minutos y 24 horas. La mayoría de los sitios utilizan el tiempo predeterminado de 30 minutos. Planee actualizar antes de que caduque.
¿Puedo compartir qa_validation_cookie entre solicitudes?
Sí, pero sólo desde la misma dirección IP y con la misma cadena de User-Agent. Cambiar cualquiera de ellos invalidará la cookie.
¿El modo bajo ataque siempre está habilitado?
No. Los operadores del sitio lo alternan manualmente durante los ataques. Algunos sitios lo dejan habilitado permanentemente como capa de seguridad adicional. No hay forma de predecir si un sitio tendrá IUAM activo.
¿Cuál es la diferencia entre IUAM y un desafío gestionado?
IUAM desafía incondicionalmente a cada visitante. Los desafíos administrados utilizan la evaluación de bots de Cloudflare para desafiar selectivamente el tráfico sospechoso. IUAM siempre devuelve 503 con un desafío JS. Los challenges administrados pueden devolver 503 con un widget de Turnstile.
¿IUAM afecta los endpoints de API?
Sí. IUAM se aplica a todas las solicitudes del dominio, incluidos los endpoints de API. Esta es la razón por la que fallan las solicitudes de API de clientes que no son navegadores: no pueden ejecutar el challenge de JavaScript.
Resumen
El modo bajo ataque de Cloudflare crea un desafío de JavaScript obligatorio para todos los visitantes, devolviendo HTTP 503 con un requisito de cálculo de 5 segundos. Resuelve los challenges IUAM con el Solucionador Cloudflare Challenge de CaptchaAI, luego usa la cookie qa_validation_cookie para solicitudes posteriores dentro del período de 30 minutos. Siempre haz coincidir la dirección IP y el User-Agent entre la resolución y el uso.
Artículos relacionados
- Cloudflare Challenge vs Turnstile: cómo detectar
- Cómo funciona Cloudflare Challenge
- Loop del Cloudflare Challenge: solución