Ilustración abstracta de pintura fluida en tonos azul marino, rojo y blanco para la noticia: El DNS secuestrado de DebugBear vació 726 carteras en Polymarket

Ciberataques

El DNS secuestrado de DebugBear vació 726 carteras en Polymarket

Polymarket cargaba el script RUM de DebugBear y, con el DNS del proveedor secuestrado, ese archivo vendió posiciones y vació 726 carteras el 29 de octubre.

A las 16:54 UTC del 29 de octubre de 2026, Cloudflare dejó de poder alcanzar el servidor de origen de cdn.debugbear.com y devolvió un error 521 a quien pedía el archivo C7xcKKrjUnXK.js, el script de monitorización de rendimiento que Polymarket cargaba en todas sus páginas. Dieciséis minutos después, a las 17:10 UTC, los primeros POL de un trader con sesión abierta llegaban a una cartera que hasta ese momento estaba vacía, y hasta las 18:02 UTC ese archivo, ya convertido en un drainer, vendió posiciones y movió fondos de 726 carteras por un valor que Polymarket cifra en 2,7 millones de dólares.

El proveedor del script, DebugBear, ha reconocido que sus registros DNS fueron modificados a través de su registrador de dominios. Polymarket ha devuelto el dinero sin que nadie tuviera que reclamar y ha añadido 1,19 millones más para quienes perdieron durante la parada de la negociación. El caso es el tercero de un proveedor externo que golpea a la plataforma en cinco meses y, en el blog, se suma a una racha de ataques a la cadena de suministro que ya pasó por una extensión de Claude Code en Cursor y por 953 tiendas Magento.

  • Qué pasó: el 29 de octubre, entre las 17:10 y las 18:02 UTC, el script RUM de DebugBear cargado en Polymarket.com fue sustituido por un drainer que vendió posiciones y movió fondos de usuarios con sesión abierta.
  • Causa: DebugBear atribuye el cambio a un compromiso de sus registros DNS a través de su registrador de dominios, sin decir todavía cuándo ni cómo.
  • Afectados: 726 carteras según Polymarket, con 2,7 millones de dólares devueltos y 1,19 millones más para 5.500 carteras perjudicadas por la parada.
  • Estado: Polymarket cerró todas las sesiones, retiró el script y volvió a desplegar los externos con CSP, versiones fijadas y sandboxing. El 1 de noviembre cdn.debugbear.com no tenía registro DNS.
  • Acción: inventariar los scripts de terceros en páginas con sesión, fijarlos con SRI o servirlos desde dominio propio y vigilar el DNS de los proveedores.

Un error 521 en cdn.debugbear.com y 52 minutos de transferencias

Gráfico de Ohey con los POL acumulados por la cartera receptora del drainer de Polymarket entre las 17:00 y las 19:00 UTC del 29 de octubre
Fuente: Ohey, «Polymarket wallet drainer served from DebugBear's script CDN»

Ohey, un servicio de vigilancia de amenazas web, reconstruyó la secuencia con copias de Internet Archive, cabeceras HTTP y datos de la cadena Polygon. Hasta la mañana del 29 de octubre, la URL del script servía el código legítimo de DebugBear, un archivo de 60.493 bytes alojado en Google Cloud Storage con ETag en formato MD5 y cabeceras x-goog. La copia archivada a las 12:06:55 UTC todavía era limpia. El archivo que recogieron los investigadores por la tarde pesaba 15.187 bytes, llevaba un ETag en formato nginx y no tenía ninguna cabecera de Cloud Storage. A las 18:13:44 UTC el host data.debugbear.com, al que el script legítimo envía sus métricas, respondía con una página 404 de nginx 1.24.0 sobre Ubuntu. Un servidor distinto contestaba por los dos nombres de DebugBear.

El gráfico de Ohey muestra el saldo en POL de la cartera receptora, leído cada tres minutos de los bloques de Polygon. Se mantiene en unos 811.000 POL entre las 17:14 y las 17:26 UTC, sube en vertical cuando el nodo de Cloudflare en Chicago cachea el drainer a las 17:27 y deja de crecer a las 18:11, doce minutos después de que Polymarket desplegara una versión sin el script. A las 18:28 el dinero empieza a salir hacia tres carteras.

Fecha y hora

Hecho

29 de octubre, 12:06:55 UTC

Última copia limpia del script archivada por Internet Archive, 60.493 bytes servidos desde Google Cloud Storage

16:54:57 UTC

Cloudflare devuelve un error 521 para cdn.debugbear.com porque el origen no responde

17:10:23 UTC

Primeros POL en la cartera receptora, en el bloque 96392296 de Polygon

17:27:45 UTC

El nodo de Cloudflare en Chicago cachea el drainer

17:38 UTC

Polymarket anuncia en su página de estado actividad no autorizada en carteras de usuarios

17:59:20 UTC

Polymarket compila una versión de la web sin el script de DebugBear

18:00:58 UTC

DebugBear comunica en X el incidente y pide retirar su código

18:02:17 UTC

Última transferencia de posiciones a la cartera receptora

18:05 UTC

El exchange pasa a modo de solo cancelación y se detiene el relayer

18:13:44 UTC

data.debugbear.com responde con un 404 de nginx 1.24.0 sobre Ubuntu

18:28:32 a 18:38:16 UTC

Tres transferencias mueven los 28.636.284 POL a otras carteras

19:00:35 UTC

Polymarket Traders anuncia que la negociación vuelve a estar operativa

20:37 UTC

cdn.debugbear.com y data.debugbear.com devuelven NXDOMAIN

30 de octubre, 14:37 UTC

Polymarket informa de 689 carteras reembolsadas de 726 y de 1,19 millones de dólares para 5.500 carteras

30 de octubre, 20:07 UTC

Informe posterior en la página de estado con 3,9 millones devueltos y nuevos controles para los scripts externos

DeFiprime, que siguió la cartera en paralelo, calculó que los 28.636.284 POL acumulados a las 18:19 UTC valían unos 2,64 millones de dólares al precio de 0,0922 dólares que daba DefiLlama en ese momento, sin contar las posiciones transferidas. El informe de Ohey añade 10.383 USDC.e y 6.320 USDC en 29 transferencias y las posiciones de 33 carteras de depósito que salieron en 36 lotes hacia una cuarta dirección.

Lo que DebugBear y Polymarket han confirmado y lo que sigue sin saberse

DebugBear vende RUM, un script que mide la velocidad de carga en el navegador de los visitantes reales. Cada cliente incrusta un archivo propio servido desde cdn.debugbear.com, y la empresa tiene unos 1.700 seguidores en LinkedIn, lo que da una idea de su tamaño. Su primer aviso llegó a las 18:00:58 UTC, un minuto y medio después de que Polymarket compilara la versión de su web sin el script.

«We're impacted by an ongoing security incident» (nos afecta un incidente de seguridad en curso), escribió la empresa en X, y pidió a todos los clientes de su producto RUM que retirasen el código de su web. No dio más detalles hasta una segunda publicación en LinkedIn, en la que atribuyó el problema a su registrador: «Our DNS server records were compromised through our domain registrar» (los registros de nuestro servidor DNS fueron comprometidos a través de nuestro registrador de dominios). En el mismo texto reconoce que no puede recibir correo en su dominio, que el ataque iba dirigido a la web de un cliente concreto y que no ha visto indicios de intrusión en sus sistemas internos, aunque sigue investigando.

Publicación de DebugBear en LinkedIn en la que reconoce que sus registros DNS fueron comprometidos a través de su registrador de dominios
Fuente: DebugBear en LinkedIn

La publicación de DebugBear deja fuera lo que más interesa a cualquiera que cargue su script: cuándo cambiaron los registros, qué registrador es, cómo se consiguió el acceso a la cuenta y si algún otro cliente recibió un archivo manipulado. Hudson Rock, que capturó el drainer, tampoco encontró indicios de que otros clientes fueran objetivo, pero ni la empresa ni los investigadores lo han descartado. Cuando The Hacker News lo comprobó el 1 de noviembre, cdn.debugbear.com ya no tenía registro DNS, y Ohey anotó respuestas NXDOMAIN para los dos hosts desde las 20:37 UTC del día 29.

Polymarket publicó su primer aviso en su página de estado a las 17:38 UTC, con una frase sobre actividad no autorizada en carteras de usuarios. A las 18:05 UTC pasó el exchange a modo de solo cancelación y detuvo el relayer, el servicio que envía a la cadena las operaciones firmadas por los usuarios. La cuenta de Polymarket Traders lo contó en X a las 18:33 UTC.

«One of our 3rd party providers was compromised» (uno de nuestros proveedores externos fue comprometido), dice el mensaje, que añade que el caso se ha remitido a las fuerzas de seguridad y que «Anyone who has been impacted will be made whole» (cualquiera que se haya visto afectado será compensado). La negociación volvió a las 19:00 UTC. En el informe posterior, publicado en la página de estado el 30 de octubre a las 20:07 UTC, la empresa enumera lo que hizo: retiró el script y vació todas las cachés, paró la negociación y el relayer hasta limpiar la web, cerró todas las sesiones activas y volvió a desplegar los scripts de terceros con una Content Security Policy más estricta, versiones fijadas y sandboxing. El mismo día, a las 14:37 UTC, Polymarket Traders detalló los reembolsos.

Las cifras de carteras no coinciden entre fuentes y conviene leerlas con cuidado. Las 726 carteras afectadas son el recuento de Polymarket. Las 33 de Ohey son solo las carteras de depósito cuyas posiciones se transfirieron directamente al atacante. GoPlus habló de 710 carteras de depósito y 731 direcciones, y DeFiprime contó 47 direcciones que enviaron USDC o tokens de resultado a la cartera receptora, advirtiendo de que ese número no equivale a víctimas. Polymarket no ha dicho cuántos usuarios de cada tipo de cuenta perdieron dinero ni ha publicado una cifra propia de lo robado más allá de los 2,7 millones que devuelve.

Cómo el drainer tomó prestado el cliente de trading de la propia página

El primer aviso público del archivo lo dio un usuario de Discord llamado Vivian, cuya captura llegó a Hudson Rock. El mensaje señalaba que el script cargado en la portada de Polymarket contenía código para acceder a credenciales, disparar firmas de cartera, vender posiciones y transferir activos, y pedía no firmar nada mientras se reunían pruebas.

Mensaje de un usuario en Discord que avisa de que el archivo C7xcKKrjUnXK.js de cdn.debugbear.com cargado en Polymarket contiene código para firmar y transferir activos
Fuente: Hudson Rock, «Polymarket Breach Alert: Wallet-Draining Code Found in a Third-Party Script»

Alon Gal, de Hudson Rock, descargó el archivo a las 18:12:06 y a las 18:13:04 UTC desde la URL que usaba Polymarket y obtuvo los mismos bytes y el mismo hash SHA-256 en las dos ocasiones. El análisis de Hudson Rock resume su enfoque en una frase: «Its central approach is to reuse authority already available in the authenticated application» (su enfoque central es reutilizar la autoridad ya disponible en la aplicación autenticada). El drainer no transporta credenciales propias ni roba la frase semilla. Según Ohey, es una única función minimizada de 15.187 bytes llamada startdebugger, sin ofuscación, que lanza tres peticiones a la vez: su configuración, la geolocalización del visitante a través de la API de geobloqueo de Polymarket y una espera de 1,5 segundos. Si Polymarket marca al visitante como bloqueado, el script no sigue.

Después lee tres claves de localStorage que la aplicación de Polymarket escribe por sí misma: polymarket.auth.params, con el tipo de inicio de sesión y la dirección, polymarket.auth.proxyWallet, con la cartera de depósito que guarda los fondos, y poly_clob_api_key_map, con las credenciales de trading de cada cartera. Separa las cuentas en dos clases: eoa, las que entran con una cartera de navegador como MetaMask, y magic, las que usan el inicio de sesión por correo de Polymarket. Un visitante sin sesión no pasa de ahí.

La parte que explica la eficacia del ataque es la segunda. El script no construye su propio cliente de trading. Busca el que la página ya tiene montado. Recorre hasta 400 botones, enlaces y contenedores y camina por sus árboles internos de React, los objetos fiber que cuelgan del DOM, durante un máximo de 5 segundos o 60.000 nodos, hasta quedarse con cualquier objeto que tenga un método postOrder y otro createOrder o createMarketOrder. Ese es el cliente de órdenes de Polymarket con su firmante ya enganchado. Con él lee los saldos de la cartera de depósito por RPC de Polygon y hasta 200 posiciones abiertas, y se detiene si la cuenta vale menos de 10 dólares.

Fragmento del script malicioso servido desde cdn.debugbear.com que construye una transferencia ERC-1155 en lote de las posiciones de Polymarket
Fuente: BleepingComputer, «Polymarket halts trading after crypto-draining script breach, $2.5M traced»

La captura de BleepingComputer muestra el tramo del código que mueve las posiciones de las cuentas eoa: una llamada safeBatchTransferFrom sobre el contrato de tokens condicionales de Polymarket, 0x4D97DCd97eC945f40cF65F87097ACe5EA0476045, que transfiere en un solo lote todos los tokens de resultado que superen los 10 dólares. Para las cuentas magic el camino es distinto, porque no puede transferir los tokens directamente: lanza órdenes de venta de tipo fill and kill al 97 % del precio, luego al 50 % y por último al tick mínimo del mercado, y barre los ingresos. En las dos ramas, cada lote de llamadas se envuelve en un mensaje EIP-712 de tipo DepositWallet, se firma con el firmante de la página y se envía a relayer-v2.polymarket.com con una hora de plazo. El efectivo se convierte a POL con una cotización de api.fun.xyz y se paga a la dirección del atacante, con USDC nativo y USDC.e como alternativas.

Hudson Rock subraya un matiz que importa a las víctimas: «A signing request is not proof of a silent signature or a completed theft» (una petición de firma no prueba una firma silenciosa ni un robo consumado). La cartera del navegador puede mostrar la petición, rechazarla o aplicar sus propias reglas, de modo que el daño real en cada cuenta depende de cómo se gestionó esa firma. Las cuentas magic, en cambio, no tenían ese filtro humano.

GoPlus, empresa de seguridad blockchain, publicó el 30 de octubre su propio desglose en X y atribuyó el robo a un compromiso de la cadena de suministro del script RUM de DebugBear. Todos los hosts a los que el drainer llamaba, salvo los dos de DebugBear, estaban en la Content Security Policy de Polymarket: los subdominios de polymarket.com para las API y el relayer, alchemy.com para el RPC y fun.xyz para los swaps. La política permitió cada petición porque cada petición iba a un host que la plataforma usa. Los indicadores que publican Ohey y Hudson Rock son estos.

Tipo

Valor

Contexto

URL

hxxps://cdn.debugbear[.]com/C7xcKKrjUnXK.js

Script RUM de Polymarket sustituido por el drainer el 29 de octubre

hash SHA-256

0755e767504d8103f6c27b9e765a1026507a17c04513242adb503df7777879e5

Drainer, 15.187 bytes

hash SHA-256

0525f046c83daa429e0f676d36650d51d9e283ba5cacfa56097c80bad586128b

Archivo RUM legítimo de la misma URL, 60.493 bytes, servido hasta el 29 de octubre

URL

hxxps://data.debugbear[.]com/metrics/init

Configuración remota del drainer, con la dirección receptora y los umbrales

URL

hxxps://data.debugbear[.]com/metrics/submit

Informe del portfolio de la víctima antes de mover nada

URL

hxxps://data.debugbear[.]com/metrics/update

Informe de cada barrido de efectivo, con destino, importe y hash de transacción

URL

hxxps://data.debugbear[.]com/metrics/handle

Informe de cada transferencia de posiciones

Cada informe al servidor de datos incluía la cartera de depósito, la cartera de inicio de sesión, el tipo de cuenta, el sistema operativo, el identificador de seguimiento 4c6b64a0-a7ef-4c0f-9c70-3a4e6f89065c y la IP y el país devueltos por la API de geobloqueo de Polymarket. Las direcciones de Polygon implicadas, según el seguimiento de Ohey, quedan así.

Dirección en Polygon

Papel

0x3F99139F1C5854bb628c2e576Aaf638e99dFfc18

Receptora fijada en el código, recibió los POL y el efectivo

0x5a2764fbbe5d139ef0ed988ec5f95320ce730c0b

Recibió las posiciones transferidas desde las cuentas con cartera de navegador

0xe4c4c39c1733e1c7c06b79f97ed442b68df41ec6

Recibió 18.613.584 POL a las 18:28:32 UTC

0x5392587814ce8c6af6789764f88e5e9ab0b9962c

Recibió 4.295.442 POL a las 18:30:41 UTC

0xc91ee0574a14446de200923729c349b9cae19b60

Recibió 5.727.258,45 POL a las 18:38:16 UTC

Qué revisar si tu web carga scripts de terceros en páginas con sesión

Este ataque no tocó los contratos de Polymarket ni sus servidores. Funcionó porque un archivo JavaScript ajeno se ejecutaba con los mismos permisos que el código propio en la pestaña de un usuario autenticado, algo que ocurre en cualquier web que carga analítica, chat, monitorización o publicidad desde dominios de terceros. El repositorio webperf-snippets, por ejemplo, retiró el script esa misma tarde porque lo cargaba en todas sus páginas. Si administras una web con área privada, banca, trading o pagos, este es el orden de trabajo.

  1. Inventaría hoy qué scripts externos cargan tus páginas con sesión y quita los que no sean imprescindibles en las vistas donde el usuario firma, paga u opera. Hudson Rock y Polymarket coinciden en ese primer paso.
  2. Si un proveedor sirve un archivo que no cambia, fíjalo con Subresource Integrity (atributo integrity con su hash SHA-384) para que el navegador rechace cualquier versión distinta. Un script RUM que se actualiza sin avisar no admite SRI, y esa es una razón para cargarlo desde tu propio dominio con una copia controlada.
  3. Revisa tu Content Security Policy con el caso delante: permitir un dominio de CDN de confianza no verifica los archivos que ese CDN sirve, y aquí todos los destinos del drainer estaban permitidos. Añade sandboxing y versiones fijadas donde el proveedor lo permita, como hizo Polymarket al volver a desplegar.
  4. Vigila la resolución DNS de los dominios de tus proveedores y guarda un registro diario. El cambio de Google Cloud Storage a un nginx sobre Ubuntu era visible en las cabeceras HTTP horas antes de que nadie lo contara. Si quieres entender qué hay detrás de una resolución, el blog tiene un repaso a DNS cifrado que explica cómo viaja una consulta.

Estos dos comandos sirven para el primer y el cuarto punto. El primero lista los scripts que una página carga desde dominios ajenos y el segundo guarda a qué apunta hoy el dominio de un proveedor para compararlo mañana.

# Scripts que una página carga desde dominios ajenos al propio
curl -s https://www.ejemplo.com/ | grep -oE '<script[^>]+src="https?://[^"]+"' | grep -v 'ejemplo.com' | sort -u

# A qué apunta hoy el dominio de un proveedor, con fecha, para compararlo mañana
echo "$(date -u +%FT%TZ) $(dig +short cdn.debugbear.com A CNAME | tr '\n' ' ')" >> dns-proveedores.log

Quedan dos puntos para quien está en los dos extremos del incidente, los clientes de DebugBear y los usuarios de Polymarket.

  1. Si usabas DebugBear RUM, retira el snippet de plantillas, plugins y gestores de etiquetas, vacía las cachés y comprueba que ya no carga. Cierra las sesiones de administración y revisa los registros del 29 de octubre entre las 16:54 y las 20:37 UTC en busca de peticiones a cdn.debugbear.com y data.debugbear.com.
  2. Si eres usuario de Polymarket y tenías sesión abierta esa tarde, revisa el historial de tu cartera en un explorador independiente, rechaza cualquier petición de firma que no esperes y, si tu reembolso no cuadra, usa el formulario que enlaza la página de estado. Una empresa española afectada por un incidente así puede notificarlo a INCIBE-CERT.

Tres incidentes de proveedor en cinco meses y un bloqueo de la DGOJ en España

El de DebugBear es el tercer incidente con un tercero de por medio que sufre Polymarket desde mayo. Según el análisis de DeFiprime, en mayo de 2026 un atacante vació unos 600.000 dólares de una cartera operativa inactiva con una clave privada filtrada, y el 25 de junio otro script malicioso inyectado por un proveedor comprometido llegó a la web y causó pérdidas cercanas a los 3 millones de dólares, con reembolso completo y sin que Polymarket nombrara nunca al proveedor. Dos días antes de este ataque, el 27 de octubre, la plataforma Predict.fun comunicó transferencias no autorizadas por unos 400.000 USDT y apuntó a su sitio de documentación de API, alojado por un tercero, aunque nada público relaciona los dos casos. Los cuatro casos quedan así.

Fecha

Incidente

Mayo de 2026

Unos 600.000 dólares vaciados de una cartera operativa inactiva de Polymarket con una clave privada filtrada

25 de junio de 2026

Script malicioso inyectado en la web de Polymarket por un proveedor comprometido, pérdidas cercanas a 3 millones de dólares y reembolso completo

27 de octubre de 2026

Predict.fun comunica unos 400.000 USDT en transferencias no autorizadas y apunta a su documentación de API alojada por un tercero

29 de octubre de 2026

Script RUM de DebugBear sustituido por un drainer en Polymarket.com, 726 carteras afectadas y 2,7 millones de dólares devueltos

Nos llama la atención que Polymarket dijera en junio que había retirado la dependencia afectada y cuatro meses después volviera a cargar un script de terceros en la misma pestaña en la que sus usuarios firman. La respuesta de esta vez fue rápida, con el despliegue sin el script 49 minutos después del primer robo y los reembolsos pagados en 24 horas, pero la medida que de verdad cambia el riesgo es la que anuncia ahora, reducir y aislar lo que se carga de fuera, y esa llega después del tercer aviso. El patrón es el mismo que vimos cuando Rank Math PRO sirvió un backdoor desde su propia web o cuando OVHcloud CLI distribuyó un stealer durante 94 minutos: el proveedor cae y el daño lo absorben sus clientes.

El anuncio de la vuelta de la negociación, a las 19:00 UTC, llegó con la promesa de reembolso completo que la empresa cumplió al día siguiente, y ese es el dato que separa este caso de otros robos en plataformas cripto.

El ataque coincidió en el tiempo con el robo de 6.300 millones a Binance del mismo 29 de octubre, y no hay ningún dato que los relacione. En el caso de Polymarket no existe atribución de ninguna autoridad ni de ningún laboratorio, y lo único que se conoce del atacante son las direcciones de Polygon a las que fue el dinero.

Hay un matiz previo para quien lee desde España. Polymarket.com está bloqueada en España desde que la Dirección General de Ordenación del Juego abrió un expediente sancionador a Polymarket y Kalshi y ordenó el bloqueo cautelar de sus webs, según la nota del Ministerio de Consumo del 26 de mayo de 2026, notificada por el BOE y con una tramitación estimada de tres a cuatro meses. Quien opere desde España lo hace saltándose ese bloqueo, y además el propio script del atacante consultaba la API de geobloqueo de Polymarket y dejaba en paz a los visitantes marcados como bloqueados. Eso no protege a nadie: el usuario que entra con una VPN no aparece como bloqueado para esa API y era un objetivo igual que cualquier otro.

Dudas de lectores sobre Polymarket tras el ataque

¿Es seguro operar en Polymarket después de este ataque?

Los contratos y los servidores de Polymarket no fueron comprometidos, el problema estuvo en el navegador del usuario. Polymarket ha cerrado todas las sesiones, así que habrá que iniciar sesión de nuevo, y afirma haber desplegado los scripts externos con controles de integridad. Quien use una cartera de navegador conserva una defensa que las cuentas por correo no tienen: la petición de firma aparece en pantalla y se puede rechazar.

¿Cuándo paga Polymarket los reembolsos del 29 de octubre?

Polymarket indicó el 30 de octubre que 689 de las 726 carteras afectadas ya habían recibido el importe completo y que las 37 restantes cobrarían según se verificara cada una. Los 1,19 millones de dólares para unas 5.500 carteras que perdieron durante la parada de la negociación empezaron a pagarse ese mismo día. No hay que presentar reclamación, y quien considere que la cantidad no cuadra tiene un formulario enlazado desde la página de estado.

¿Por qué no funciona Polymarket desde España?

Porque el acceso a Polymarket.com está bloqueado de forma cautelar por orden de la Dirección General de Ordenación del Juego desde finales de mayo de 2026, mientras se tramita un expediente sancionador por operar sin licencia de juego. Ese bloqueo es una medida administrativa española y no tiene relación con el incidente de DebugBear ni con la parada de la negociación del 29 de octubre.

Temas

No hay comentarios todavía