Saltar al contenido
17 min de lectura

LiteLLM ataque supply chain y pasos de contención

Compartir

Por Lucas Andrade ·

LiteLLM ataque supply chain el 21 de octubre de 2026 dejó la 1.107.0 maliciosa en PyPI y Docker. Revisa ventana UTC, IoCs y pin en 1.106.2

En este artículo

LiteLLM ataque supply chain, el 21 de octubre de 2026, publicó la versión 1.107.0 con malware en PyPI y en imágenes Docker. LiteLLM es una puerta de enlace en Python que unifica proveedores de modelos de lenguaje. El paquete suele ejecutarse cerca de claves de nube y de LLM.

Si tu equipo instaló esa versión o tiró de etiquetas flotantes oficiales en la ventana incorrecta, el riesgo no se limita al paquete. Además, la carga útil entra en el entorno Python y puede ejecutarse en cualquier arranque del intérprete, aunque no importes LiteLLM. Por eso la prioridad es contener, limpiar hooks, reconstruir y rotar secretos alcanzables.

Esta guía se mantiene en el ángulo de defensa y desarrollo. Así sales con la ventana en UTC y con el perímetro claro. Después ves cómo probar exposición y qué rotar. Luego fijas la litellm 1.106.2 versión segura y separas lo que sigue en investigación.

¿Qué ocurrió y cuál fue la ventana en UTC?#

El 21 de octubre de 2026 la cadena de publicación de LiteLLM fue comprometida y la versión 1.107.0 salió con un stealer de credenciales y un cargador de código remoto. El artefacto malo llegó a PyPI y a imágenes oficiales, de modo que cualquier instalación o pull en esa franja debe tratarse como exposición potencial.

¿Cuál fue la ventana UTC en PyPI y en Docker?#

Según el aviso oficial del incidente, actualizado el 21 de octubre de 2026 a las 20h30 UTC, el paquete litellm==1.107.0 estuvo vivo en PyPI cerca de dos horas. La ventana de PyPI fue de 11h39 UTC a 13h23 UTC. En cambio, las imágenes de Docker Hub v1.107.0, latest, main-latest y main-stable apuntaron al índice comprometido de 11h46 UTC a 14h20 UTC.

El digest citado en el aviso para la imagen mala en Docker Hub es sha256:1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339e. En GHCR, las etiquetas equivalentes quedaron comprometidas desde las 11h46 UTC. Después quedaron indisponibles hasta cerca de las 13h51 UTC. La etiqueta de código v1.107.0 en el repositorio legítimo no cargaba los archivos maliciosos. Por lo tanto, los artefactos salieron de un repositorio controlado por el atacante.

¿Por qué la etiqueta Git limpia no bastaba?#

El análisis de JFrog Security Research confirma que las siete wheels de la 1.107.0 llevaban la carga útil. En contraste, el tarball de fuente no traía los mismos tres archivos de arranque. Así, quien solo revisa la etiqueta Git o el sdist puede creer que el release está limpio. Aun así, la wheel mala puede entrar en el host. The Register describió el caso el mismo día como distribución de malware de robo de secretos y de un RAT mediante PyPI y registros Docker.

En la práctica, lo que veo con más frecuencia es que el equipo trata “dos horas en el aire” como una ventana demasiado pequeña para inventariar. Sin embargo, en CI con caché, en rebuild automático y en pull de latest, esa ventana basta para contaminar runner, notebook y proxy. El reloj útil es el UTC del instalador y del registro, y no el huso del escritorio.

¿Quién se ve afectado en PyPI, Docker y quién fija la versión?#

Entras en el perímetro si instalaste litellm==1.107.0 en el intervalo de PyPI, o si ejecutaste imagen v1.107.0, latest, main-latest o main-stable en el intervalo Docker. Quien fija una versión antigua y no tiró de la 1.107.0 en esa ventana queda fuera del artefacto malo, aunque aún debe validar lockfiles, cachés e imágenes locales.

El aviso oficial separa usuarios open source de clientes enterprise en el registro privado. En OSS, pip sin pin o imagen con etiqueta flotante en la ventana debe tratarse como comprometido. En enterprise, LiteLLM afirma que el registro privado usado para distribución embargada no fue afectado. Eso solo vale si la instalación vino realmente de ese canal privado. En caso contrario, PyPI público y etiquetas públicas de Docker Hub o de GHCR entran en el mismo riesgo.

Quien “fija versión” en el día a día también cambia la exposición. Dependabot, renovate, imagen base sin digest y pip install -U litellm sin hash amplían la chance de atrapar la 1.107.0. Además, nadie necesita notar el número en el momento. El Datadog Security Labs resume la superficie en paquete PyPI y etiquetas GHCR y Docker Hub. También recuerda el volumen alto de descargas semanales, lo que explica la urgencia del inventario aunque hayan sido pocas horas de exposición.

CanalArtefacto maloVentana UTC el 2026-10-21Acción mínima
PyPIlitellm==1.107.0 (siete wheels)11h39–13h23Tratar host o venv como comprometido si Python corrió
Docker Hubv1.107.0, latest, main-latest, main-stable11h46–14h20Confirmar digest y hora del pull
GHCRmismas etiquetas en litellm, litellm-database, litellm-non_rootdesde 11h46 hasta indisponibilidad ~13h51Reconstruir desde un digest bueno
Enterprise privadoregistro privado (según LiteLLM)no listado como afectadoConfirmar el origen real del artefacto

El error que más cuesta caro aquí es asumir que “no usamos Docker, entonces estamos bien”, o lo contrario. LiteLLM PyPI comprometido y LiteLLM Docker supply chain son vectores paralelos del mismo release. Por eso el inventario necesita cruzar lockfile, historial de pip, digest de imagen y hora UTC del job.

¿Cómo saber si instalaste la versión mala?#

Empieza por el historial de instalación y por el digest, y no por la intuición del equipo. Si pip show litellm ya apuntó a 1.107.0 en algún momento de la ventana, el entorno debe tratarse como comprometido. Lo mismo vale si el contenedor ejecutó el digest comprometido, incluso aunque el paquete ya se haya quitado del índice público.

Busca evidencia de litellm-1.107.0.dist-info y de wheels 1.107.0 en caché. También busca builds que instalaron la versión sin pin entre 11h39 UTC y 13h23 UTC el 21 de octubre de 2026. En contenedores, compara el digest tirado con sha256:1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339e. Hallar uno de estos signos confirma exposición. No hallar nada, no obstante, no limpia el entorno, porque la limpieza de /tmp, el rebuild y la rotación de volúmenes borran rastros.

La Socket registró que su escáner marcó las wheels minutos después de la publicación. Además, la procedencia de la imagen apuntaba al repositorio lookalike Berri-AI/litellm, y no al BerriAI/litellm legítimo. Eso ayuda a explicar por qué la etiqueta de fuente “oficial” puede parecer limpia mientras el artefacto instalable no lo estaba. Si tu pipeline solo valida la etiqueta Git, podía pasar en verde y aun así entregar LiteLLM 1.107.0 malicioso.

Mucha gente cree que desinstalar el paquete borra el problema, y casi siempre se equivoca, porque los hooks fueron a la raíz de site-packages. Por eso la comprobación de versión debe ir junto con la caza de cook.pth, cook.py y un sitecustomize.py inesperado. Sin los dos ejes, solo cierras la mitad del inventario.

¿Qué indicadores de compromiso listan el aviso oficial y los análisis?#

Los IoC más útiles hoy mezclan archivos de arranque, artefactos en /tmp, dominio de exfiltración y digest de la imagen. El aviso oficial pide buscar litellm-1.107.0.dist-info, cook.pth y sitecustomize.py. También orienta a matar el daemon Python que sostiene /tmp/remote_code_loader.lock antes de cualquier pip en el entorno sucio.

JFrog publica una lista operativa alineada con ese cuadro. Entre las señales están el dominio www.litellm.dev y la ruta /healthcheck. También aparecen el dead-drop raw.githubusercontent.com/letters9813/pythonclient-test/main/domain.txt, el marcador /tmp/.pc_once_72129118c59f5636c0bb, artefactos /tmp/.pc_sq_ y /tmp/.pc_e_, además del digest de la imagen afectada. Según The Register, el cazador de Aikido también destacó /tmp/.pc_once_* como señal de exfiltración ya disparada. El lock del loader, a su vez, apunta a C2 activo o reciente.

El mecanismo importa para la caza. cook.pth fuerza el import de cook.py en el arranque de Python. sitecustomize.py levanta el loader en segundo plano. Así, cualquier python, pip o job en el venv puede volver a disparar el malware. En respuesta a incidente, el primer reflejo equivocado es abrir el venv y “solo correr un pip show”. Si el intérprete sucio arranca, puedes reejecutar la carga útil mientras intentas diagnosticar.

Prefiere herramientas de shell y filesystem que no invoquen ese Python. Aísla la máquina y preserva logs de DNS, proxy y nube antes de una limpieza agresiva. La ausencia del lock en un host no prueba ausencia del robo de credenciales LiteLLM, porque el contenedor efímero y la limpieza de /tmp eliminan la prueba con facilidad.

LiteLLM ataque supply chain exige rotar qué secretos?#

Si la 1.107.0 corrió en un host con salida a internet, el aviso oficial pide asumir que la exfiltración pudo haber ocurrido. El marcador de ejecución única confirma cuando existe. La ausencia del marcador no inocenta, porque el contenedor efímero y la limpieza de /tmp borran la prueba.

La lista mínima del comunicado oficial incluye el rol IAM de la instancia o task. También incluye todas las claves de proveedor guardadas en la base del proxy LiteLLM, master key y virtual keys, la contraseña de DATABASE_URL y cualquier secreto presente en el entorno de procesos de ese host. Después, la propia LiteLLM recomienda mirar CloudTrail por GetCallerIdentity del role en la hora de la instalación y por uso de ese material fuera de tu infraestructura. Para el flujo AWS, conviene ordenar primero los logs de identidad y acceso sin confundir síntoma con causa.

Los análisis de Wiz y de JFrog amplían el inventario más allá del proxy. Describen recolección de credenciales de navegador, AWS, Azure y GCP, tokens y configs de herramientas de IA, claves SSH y GPG, secretos de CI y variables de entorno legibles. Wiz habla de módulos amplios de recolección en browser, nube y servicios de IA. Trátalo como hipótesis fuerte de superficie, y no como prueba de que cada módulo se disparó en tu caso. Aun así, la rotación debe cubrir todo lo que el host podía alcanzar, porque el costo de dejar una clave viva suele superar el de rotar temprano.

Cuando el entorno parece “solo un sandbox de prompt”, el riesgo cambia poco si había clave real de proveedor, token de nube o volumen montado con ~/.aws. Rota, revoca y regenera. Luego audita el uso. Limpiar archivo sin rotar secreto deja la puerta abierta a quien ya recibió el paquete cifrado.

¿Cómo fijar la versión y verificar hash o firma?#

La versión segura señalada de forma consistente por el aviso oficial, por JFrog, por Endor Labs y por The Register es la 1.106.2. Sin embargo, el pin correcto no es el primer comando. Si el entorno ya ejecutó la 1.107.0, empezar con pip install en el mismo Python puede rearmar cook.pth y sitecustomize.py.

¿Por qué no empezar con pip install?#

Endor Labs refuerza que el ataque vive en el empaquetado. La etiqueta revisada, por sí sola, no muestra el cambio de build. Por eso, cualquier comando que levante el Python sucio puede rearmar los hooks. Así, diagnóstico y remediación necesitan empezar fuera de ese intérprete.

Orden defensiva de contención y pin#

Sigue esta orden defensiva, adaptada del comunicado oficial y de las notas de JFrog.

  1. Aísla el host o el contenedor y preserva logs de red, DNS, endpoint y nube antes de borrar evidencia útil.
  2. Elimina cook.pth, cook.py, sitecustomize.py y los *.pyc correspondientes en __pycache__ de cada site-packages afectado, usando herramientas que no inicien el Python comprometido.
  3. Termina el proceso detached asociado a /tmp/remote_code_loader.lock e inspecciona marcadores /tmp/.pc_once_, /tmp/.pc_sq_ y /tmp/.pc_e_*.
  4. Reconstruye el venv o la imagen desde cero y fija litellm==1.106.2, de preferencia con hash de la wheel buena y digest inmutable de la imagen buena.
  5. Solo entonces rota los secretos alcanzables y audita el uso posterior de esos secretos.

Verificar hash y firma reduce reincidencia, pero no sustituye el rebuild. Socket mostró que la procedencia del build puede registrar una fuente lookalike con apariencia casi legítima. Por eso, pin por número sin pin por hash todavía deja espacio para un artefacto cambiado en el próximo incidente. Confirmar digest de imagen, hash de wheel y origen del repositorio necesita volverse hábito de release, y no un ritual solo después del susto.

El atajo que más atrasa la contención es “arreglar en el sitio” y seguir con el mismo volumen sucio. Rebuild desde un artefacto verificado cuesta tiempo ahora y evita un falso negativo caro después. Si hay duda entre limpiar y recrear, recrear gana en la mayor parte de los proxies y runners de IA.

¿Open source y enterprise difieren en este incidente?#

Sí, y la diferencia viene del canal de distribución, no de una inmunidad mágica. LiteLLM afirma que los clientes en el registro privado enterprise no fueron impactados por este release público 1.107.0. Quien tiraba de PyPI público o de las etiquetas públicas de Docker Hub y GHCR entra en el escenario OSS descrito en el aviso.

Hay un detalle adicional en el propio comunicado. La empresa menciona un release embargado en el canal privado ligado a una vulnerabilidad con divulgación prevista para el 27 de octubre de 2026. Eso es independiente del malware de la 1.107.0 y no debe leerse como “enterprise ya está parcheado para todo”. Significa solo que el registro privado no fue el canal del artefacto troyanizado de este incidente, conforme a la fuente oficial.

Datadog observa además que este es el segundo compromiso de supply chain de LiteLLM en 2026. En el momento de su análisis, no había vínculo establecido con el episodio anterior asociado por su investigación a la actividad TeamPCP. Sin una fuente primaria nueva que atribuya un actor nombrado a este caso del 21 de octubre de 2026, el texto defensivo debe hablar de atacante y de repositorio lookalike, conforme al consenso de las fuentes abiertas, y no de un grupo específico.

En operación mixta, el riesgo práctico es que el equipo enterprise crea que “somos clientes, entonces terminó” mientras un job paralelo todavía instala desde PyPI. Confirma el registro real de cada entorno. Si un solo clúster tira de ambos mundos, la exención del canal privado no cubre el nodo que bebió de la fuente pública.

¿Cómo reducir el riesgo de supply chain en dependencias de IA?#

Después de la contención, la ganancia está en hacer más cara la próxima sustitución de artefacto para el atacante y más visible para ti. Pin de versión exacta, pin de hash en Python, digest inmutable en imagen y prohibición de latest en producción son el piso. Encima de eso, bloquea etiquetas flotantes en CI de gateway de LLM y exige revisión humana cuando el lockfile suba la versión de un proxy que guarda claves.

Monitorea el egreso hacia dominios lookalike y hacia dead-drops en raw de GitHub. En este caso, el dominio de exfiltración citado por los análisis técnicos era una variación cercana a la marca. Además, trata los startup hooks en site-packages como superficie de persistencia. La caza de persistencia encaja cuando la carga útil sobrevive a la eliminación del paquete principal. Para el proceso continuo, un programa de gestión de vulnerabilidades necesita incluir dependencias de IA con el mismo rigor de una lib web clásica.

Hay un límite claro. Ninguna de estas medidas elimina la supply chain. Reducen la ventana, aumentan la chance de detección y disminuyen el radio de impacto cuando se filtra un token de release. Separar entornos que guardan claves de proveedor, usar secreto de corta duración y evitar notebook con role amplio sigue siendo defensa real, incluso con escáner de paquetes en el pipeline.

Hasta la actualización oficial del 21 de octubre de 2026 a las 20h30 UTC, LiteLLM decía haber identificado la cadena de ataque con alto grado de confianza, aunque la investigación seguía en curso. En las fuentes abiertas conferidas no hay un CVE clásico de “bug de código” de la 1.107.0, porque el núcleo del caso es el artefacto troyanizado en la distribución. Tampoco hay atribución pública consolidada a un grupo nombrado con fuente primaria para este evento. Datadog afirma de forma explícita que el vínculo con el incidente anterior de 2026 no estaba establecido en su texto.

El hábito que más diferencia a un equipo maduro de uno apresurado es rechazar un rebuild “rápido” con etiqueta móvil después del incidente. Si la corrección de ayer usó latest, la próxima 1.10x.y mala puede entrar por la misma puerta. La disciplina de artefacto es tediosa y es exactamente lo que este caso castigó.

Preguntas frecuentes sobre LiteLLM ataque supply chain#

Esta sección responde dudas reales de quien opera proxy de LLM, CI y notebooks el mismo día del incidente. Las respuestas parten del aviso de LiteLLM del 21 de octubre de 2026 y de los análisis técnicos abiertos de JFrog, Datadog, Socket, Wiz, Endor Labs y The Register. No sustituyen la forense de tu entorno, porque caché, volumen y hora de pull cambian el encuadre de cada host y exigen evidencia local antes de cerrar el caso.

¿Necesito rotar claves si solo probé la imagen y ya borré el contenedor?#

Sí, si el contenedor con la imagen mala llegó a ejecutarse y tenía salida de red o montaje con secretos, la rotación sigue siendo necesaria. Borrar el contenedor elimina el filesystem efímero, pero no invalida material ya exfiltrado. El aviso oficial es explícito al pedir asumir exfiltración cuando la 1.107.0 corrió con internet. Rota claves de proveedor, secretos de entorno y credenciales de nube alcanzables, y después audita usos fuera de la ventana legítima.

¿La etiqueta Git limpia de la 1.107.0 significa que puedo confiar en el release?#

No. El aviso oficial y Socket muestran que la etiqueta de fuente legítima no contenía los archivos maliciosos, mientras que wheels e imágenes se construyeron desde un repositorio lookalike. Confiar solo en la etiqueta Git o en el sdist era exactamente el punto ciego de este caso. Para la instalación, lo que importa es la wheel o el digest que el entorno realmente descargó, con hash y origen confirmados.

¿Desinstalar litellm con pip ya elimina el malware?#

En muchos casos no basta como primer paso, y puede ser peligroso si el comando levanta el Python sucio. Los archivos cook.pth, cook.py y sitecustomize.py viven en la raíz de site-packages y se disparan en el arranque. La orientación convergente es quitar esos hooks sin invocar el intérprete afectado, tumbar el loader, reconstruir el entorno y solo entonces instalar la 1.106.2 fijada. Trata el uninstall aislado como incompleto hasta probar la ausencia de los hooks y de los artefactos en /tmp.

¿Los clientes enterprise están seguros de forma automática?#

Solo si la instalación vino del registro privado que LiteLLM declara no afectado. Si algún entorno enterprise también tiraba de PyPI público o de etiquetas públicas latest, main-stable o main-latest en la ventana del 21 de octubre de 2026, ese entorno entra en el mismo playbook del OSS. La pregunta útil no es el contrato comercial. Es la URL y el digest reales del artefacto en cada clúster.

¿Cuál es la diferencia práctica entre este caso y un CVE de código?#

Aquí el problema central es la supply chain del artefacto publicado, y no un bug documentado con CVSS en el código de la etiqueta limpia. Por eso las acciones inmediatas giran en torno a inventario de versión, digest, hooks de arranque y rotación de secreto. Aunque no haya un CVE clásico publicado en las fuentes conferidas, el impacto operativo puede ser alto, porque la carga útil corre temprano y apunta a credenciales de nube y de LLM en el mismo host.

Conclusión#

Si tu entorno tocó la 1.107.0 en la ventana del 21 de octubre de 2026, el orden que mejor protege a la mayoría de los equipos es aislar, quitar hooks sin rearmar Python, reconstruir con litellm==1.106.2 fijada por hash o digest, rotar todo lo que el host podía alcanzar y auditar el uso de las claves. Esperar un informe perfecto antes del inventario solo amplía el tiempo en que una credencial viva sigue siendo útil para quien ya recolectó el paquete.

La respuesta cambia cuando demuestras, con origen y hora, que nunca instalaste la wheel mala y nunca tiraste de las etiquetas flotantes en la ventana Docker. En ese caso, todavía conviene endurecer pin y monitoreo, pero la contención forense deja de ser el centro. El primer paso concreto ahora es listar hosts, runners y proxies con LiteLLM y marcar cuáles pasaron por pip o pull entre 11h39 UTC y 14h20 UTC ese día.

Este texto tiene carácter informativo y educativo sobre el incidente de cadena de suministro de LiteLLM del 21 de octubre de 2026. No sustituye una evaluación profesional de seguridad, una respuesta a incidente ni un análisis forense en tu entorno concreto.

Perguntas frequentes

¿Necesito rotar claves si solo probé la imagen y ya borré el contenedor?
Sí, si el contenedor con la imagen mala llegó a ejecutarse y tenía salida de red o montaje con secretos, la rotación sigue siendo necesaria. Borrar el contenedor elimina el filesystem efímero, pero no invalida material ya exfiltrado. El aviso oficial es explícito al pedir asumir exfiltración cuando la 1.107.0 corrió con internet. Rota claves de proveedor, secretos de entorno y credenciales de nube alcanzables, y después audita usos fuera de la ventana legítima.
¿La etiqueta Git limpia de la 1.107.0 significa que puedo confiar en el release?
No. El aviso oficial y Socket muestran que la etiqueta de fuente legítima no contenía los archivos maliciosos, mientras que wheels e imágenes se construyeron desde un repositorio lookalike. Confiar solo en la etiqueta Git o en el sdist era exactamente el punto ciego de este caso. Para la instalación, lo que importa es la wheel o el digest que el entorno realmente descargó, con hash y origen confirmados.
¿Desinstalar litellm con pip ya elimina el malware?
En muchos casos no basta como primer paso, y puede ser peligroso si el comando levanta el Python sucio. Los archivos cook.pth, cook.py y sitecustomize.py viven en la raíz de site-packages y se disparan en el arranque. La orientación convergente es quitar esos hooks sin invocar el intérprete afectado, tumbar el loader, reconstruir el entorno y solo entonces instalar la 1.106.2 fijada. Trata el uninstall aislado como incompleto hasta probar la ausencia de los hooks y de los artefactos en /tmp.
¿Los clientes enterprise están seguros de forma automática?
Solo si la instalación vino del registro privado que LiteLLM declara no afectado. Si algún entorno enterprise también tiraba de PyPI público o de etiquetas públicas latest, main-stable o main-latest en la ventana del 21 de octubre de 2026, ese entorno entra en el mismo playbook del OSS. La pregunta útil no es el contrato comercial. Es la URL y el digest reales del artefacto en cada clúster.
¿Cuál es la diferencia práctica entre este caso y un CVE de código?
Aquí el problema central es la supply chain del artefacto publicado, y no un bug documentado con CVSS en el código de la etiqueta limpia. Por eso las acciones inmediatas giran en torno a inventario de versión, digest, hooks de arranque y rotación de secreto. Aunque no haya un CVE clásico publicado en las fuentes conferidas, el impacto operativo puede ser alto, porque la carga útil corre temprano y apunta a credenciales de nube y de LLM en el mismo host.

Compartir

Compartir

Related posts

Aún no hay comentarios

Sé el primero en comentar.

Deja tu comentario

Inicia sesión con tu cuenta de Canverly para comentar. Puedes usar la misma cuenta en cualquier sitio de la red.

Iniciar sesión con Canverly