Explicaciones Técnicas

Cómo manejar Cloudflare en modo ataque

Tu script recibe un HTTP 503 y la pantalla "Comprueba tu navegador antes de acceder" en vez de los datos que esperabas: eso es el modo bajo ataque (IUAM) de Cloudflare. Es su defensa anti-DDoS más agresiva y obliga a cada visitante a superar un desafío de JavaScript de 5 segundos antes de dejar pasar una solicitud. Los operadores lo activan a mano durante un ataque o lo dejan siempre encendido en sitios sensibles.

Para cualquier flujo automatizado el problema es el mismo: un cliente HTTP normal no ejecuta ese JavaScript y nunca llega al contenido. Aquí verás cómo reconocer IUAM, por qué frena a esos clientes y cómo atravesarlo con CaptchaAI reutilizando la cookie de autorización.


Qué ocurre cuando un sitio activa IUAM

Cuando el operador activa el modo bajo ataque desde el panel de Cloudflare, el recorrido de cada solicitud pasa a ser este:

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

Anatomía de la página de desafío

  • jschl_vc: código de verificación del desafío
  • pass: token de temporización que impone la espera de 5 segundos
  • jschl_answer: respuesta calculada por JavaScript
  • cf_chl_opt: opciones del desafío
  • ray: el Ray ID de Cloudflare asociado a la solicitud
  • "Comprueba tu navegador antes de acceder...": el mensaje visible para el usuario

Señales que confirman que es IUAM

Estas cinco señales distinguen a IUAM de un bloqueo cualquiera:

Señal Qué significa
Código HTTP 503 Nunca un 403; ese lo devuelve un bloqueo del WAF
Espera obligatoria de 5 segundos No puedes enviar la respuesta antes de tiempo
JavaScript imprescindible Los clientes HTTP simples se quedan fuera
Cookie qa_validation_cookie Válida unos 30 minutos; habilita las siguientes solicitudes
Alcance de todo el dominio Cada página del sitio muestra el mismo desafío

Cómo distinguir IUAM de 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})"

Y resumido en una tabla de decisión rápida:

Señal IUAM Managed Challenge Turnstile Bloqueo WAF
Estado HTTP 503 503 200 403
jschl en el cuerpo
Espera de 5 segundos A veces
qa_validation_cookie establecida Al resolver Al resolver
Página de challenge Página completa Página completa Solo el widget Página de error
Requiere JS

Por qué el desafío de JavaScript frena a los clientes HTTP

El desafío de IUAM existe para comprobar que detrás de la petición hay un navegador de verdad, no un cliente HTTP básico:

Paso a paso del desafío

  1. Cloudflare entrega la página de desafío con JavaScript ofuscado.
  2. El JavaScript ejecuta sus cálculos: operaciones matemáticas sobre cadenas de la propia página, mediciones del DOM y control del tiempo (un mínimo de 4-5 segundos).
  3. Se obtiene la respuesta: un valor numérico derivado del desafío.
  4. El formulario se envía solo a Cloudflare con jschl_vc, pass y jschl_answer.
  5. Cloudflare valida la respuesta y los tiempos.
  6. Devuelve la cookie qa_validation_cookie y concede acceso durante unos 30 minutos.

A un cliente HTTP plano le falta todo lo anterior:

# 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

Resolver IUAM con CaptchaAI

Método 1: el solver de Cloudflare Challenge (recomendado)

El método cloudflare_challenge de CaptchaAI resuelve los desafíos IUAM de forma directa, sin que tengas que abrir un navegador:

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 de navegador con CaptchaAI

Para mantener una sesión persistente, combina un navegador headless 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()

El mismo flujo en 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)

Preguntas frecuentes

Las dudas más frecuentes al automatizar IUAM giran en torno a la cookie, la IP y cuándo conviene abrir un navegador.

¿Por qué el desafío vuelve a aparecer cada vez que cambio de IP?

Porque la cookie qa_validation_cookie queda atada a la IP y al User-Agent con los que se resolvió. Si sales por otra IP, Cloudflare la invalida y vuelve el 503. Resuelve y navega desde la misma salida de red autorizada.

¿Necesito un navegador headless o me basta con la API de CaptchaAI?

Depende del flujo. Si solo necesitas la autorización para lanzar solicitudes con requests o Axios, basta el Método 1 con el solver de Cloudflare Challenge. Reserva el navegador headless (Método 2) para sesiones largas donde ya manejas cookies y estado en el navegador.

¿En qué se diferencia IUAM de un Managed Challenge?

IUAM desafía a todos por igual: siempre responde con un 503 y una página completa de JavaScript. El Managed Challenge usa la evaluación de bots de Cloudflare para filtrar solo al tráfico sospechoso y puede mostrarse como un widget de Turnstile.

¿Qué hago si aparece un widget de Turnstile en vez de la página 503?

Ese sitio no está en IUAM: usa Turnstile o un Managed Challenge. Cambia al método turnstile de CaptchaAI. Si aparecen los dos seguidos, resuelve primero la página completa y luego el widget.

¿El modo bajo ataque afecta también a las llamadas a la API del sitio?

Sí. IUAM cubre todo el dominio, incluidos sus endpoints de API. Por eso fallan las peticiones de clientes que no son navegadores: no ejecutan el JavaScript. Resuelve una vez, guarda la cookie y reutilízala después.


Resolución de problemas frecuentes

Problema Causa Cómo resolverlo
El challenge se repite sin parar La IP cambió después de obtener la autorización Usa la misma IP para resolver y para acceder
qa_validation_cookie rechazada El User-Agent no coincide Usa el mismo User-Agent al resolver y al solicitar
El 503 sigue apareciendo tras resolver La cookie caducó (>30 min) Renueva la autorización antes de que expire
La página de challenge no es la esperada El sitio usa Managed Challenge, no IUAM Cambia al método de Turnstile
Aparecen varias páginas de challenge El primero es IUAM y el segundo es Turnstile Resuélvelos en orden, uno tras otro

En resumen

El modo bajo ataque de Cloudflare planta un desafío de JavaScript obligatorio con HTTP 503 y una espera de 5 segundos que ningún cliente HTTP simple supera.

La vía práctica es resolverlo con el solver de Cloudflare Challenge de CaptchaAI y reutilizar la cookie qa_validation_cookie durante sus ~30 minutos de vigencia.

Antes de automatizar, ten presente lo esencial:

  • IUAM responde con HTTP 503 y exige un desafío de JavaScript de 5 segundos; un 403 es otra cosa.
  • El Método 1 con cloudflare_challenge basta para lanzar solicitudes; deja el navegador headless para sesiones largas.
  • Reutiliza la cookie qa_validation_cookie siempre con la misma IP y el mismo User-Agent, o volverás directo al 503.

Artículos relacionados

Los comentarios están deshabilitados para este artículo.