Ir al contenido
Guide

LiteLLM tiene una puerta trasera: audite su cadena de herramientas de IA esta semana

| 8 min read

TeamPCP envió malware para robar credenciales dentro de una versión LiteLLM y drenó claves AWS, GCP y SSH de las máquinas de desarrollo. Cinco comprobaciones para ejecutar antes de la próxima instalación de pip.

Server rack representing supply chain infrastructure and credential exposure
Photo by Taylor Vick on Unsplash

En marzo de 2026, un actor de amenazas que se hacía llamar TeamPCP publicó una versión manipulada de litellm, la biblioteca de Python que incluye más de 100 proveedores de LLM detrás de un solo Interfaz compatible con OpenAI. La versión envió un ladrón de información conectado a la ruta posterior a la instalación. Cualquiera que haya corrido pip install litellm durante la ventana se entregaron las claves privadas SSH, Credenciales de AWS, tokens de Azure, JSON de cuentas de servicio de GCP y Docker config.json archivos a un punto final controlado por el atacante. The Hacker News, Ardan Labs y Security Boulevard cada uno confirmó la atribución y la lista de artefactos exfiltrados.

LiteLLM no es oscuro. Se encuentra dentro de los marcos de los agentes, dentro de los canales de CI que enrutan la evaluación. tráfico entre proveedores, dentro de los cuadernos Jupyter en la computadora portátil de un científico de datos que también contiene Credenciales de nube de larga duración. Una única versión comprometida le dio al atacante una billetera de proveedor claves, un conjunto de roles en la nube y el material SSH para mover lateralmente a cada repositorio esas claves podría alcanzar.

No se puede evitar que roben el token PyPI de un mantenedor. Puedes reducir el radio de explosión. para que cuando llegue la próxima biblioteca de IA; y lo será; una computadora portátil no se convierte en una incidente entre nubes. Aquí hay cinco comprobaciones que vale la pena realizar esta semana en toda la IA. cadena de herramientas: LiteLLM, LangChain, LlamaIndex, contenedores Ollama, Claude SDK, clientes MCP y todos marco de agente que tiene en producción.

Lo que realmente tomó TeamPCP

La carga útil corrió hacia el interior. setup.py y un gancho posterior a la instalación. Al importarlo o instalarlo lea lo siguiente en el directorio de inicio del desarrollador y en el sistema de archivos CI Runner:

  • ~/.ssh/id_rsa, id_ed25519, y known_hosts
  • ~/.aws/credentials y ~/.aws/config perfiles
  • ~/.azure/ tokens y actualizar credenciales
  • PCG application_default_credentials.json y archivos JSON de cuenta de servicio
  • ~/.docker/config.json incluyendo tokens de autenticación de registro
  • Variables de entorno que comienzan con AWS_, GCP_, OPENAI_, ANTHROPIC_, GITHUB_

El canal de exfiltración era un simple POST HTTPS para un dominio atacante que rotaba semanalmente. Derribo sucedió en cuestión de días, pero esa ventana fue suficiente; Las credenciales que se filtraron no se pueden desbloquear. A los cheques.

Comprobación 1: fijar versiones exactas, no rangos

La ^1.14.0 y ~=1.48 patrones en requirements.txt, pyproject.toml, y package.json dejar que cualquier nuevo lanzamiento menor o parche rodar en un ambiente limpio durante la noche. Así es como una ventana maliciosa de tres horas se convierte en un exposición de un mes; su archivo de bloqueo nunca se regeneró pero su caché de CI eliminó el error versión en su próxima compilación en frío.

Fijar versiones exactas. Pin por hash cuando el ecosistema lo admita.

Con --require-hashes, pip se niega a instalar cualquier cosa cuyo SHA-256 no coincida lo que generaste en el momento del bloqueo. Una versión comprometida con la misma cadena de versión pero con una Un hash tarball diferente falla en la instalación. Par pip-compile --generate-hashes con un Trabajo de CI que regenera el archivo hash solo en actualizaciones de dependencia explícitas, nunca de forma simple instalar.

Los usuarios de poesía obtienen la misma red de seguridad a través del archivo de bloqueo. El problema es la sintaxis del cursor en pyproject.toml; reemplácelo con pines exactos:

poetry install --sync elimina cualquier paquete que no esté en el archivo de bloqueo, lo que detiene una dependencia perdida se esconde entre implementaciones. Para herramientas de IA del lado npm, utilice npm ci (no npm install) en cada ejecución y confirmación de CI package-lock.json.

Comprobación 2: aislar las credenciales de los shells de desarrollo

Una shell de desarrollo que tiene ~/.aws/credentials con una clave de acceso de larga duración es un cargado Pistola apuntando a su factura de nube y a sus datos de cliente. LiteLLM no necesitaba esas credenciales para hacer su trabajo; se quedaron en el disco porque el desarrollador una vez ejecutó aws configure y nunca limpiado.

Mueva las credenciales del disco. Cárguelos a pedido, acórtelos y revoque el persistente capa:

  • AWS: aws sso login con una duración de sesión limitada de 8 a 12 horas. Borrar ~/.aws/credentials. Todo debería pasar ~/.aws/sso caché que caduca por sí solo.
  • PCG: gcloud auth application-default login con --lifetime=43200. Revocar los JSON de cuentas de servicio de larga duración que se encuentran en las computadoras portátiles; Utilice la federación de identidades de cargas de trabajo de CI.
  • Azur: az login con acceso condicional que obliga al MFA; matar tokens de actualización almacenados con más de 12 horas.
  • Claves API: guárdelos en 1Password, Vault o Doppler. Inyectar al inicio del proceso vía op run o vault read. Nunca los exportes a ~/.zshrc.

Si TeamPCP hubiera encontrado solo tokens de sesión STS vencidos, el radio de explosión se detendría en unas pocas horas. de acceso. El incidente ocurrió porque las claves de larga duración se encontraban en texto plano en el disco, listas para ser leer.

Comprobación 3: escanea cada instalación con un sandbox

Antes de confiar en una nueva biblioteca de IA o en la actualización de una existente, instálela en algún lugar donde no puede acceder a sus credenciales. Un contenedor Docker desechable con capacidades descartadas y El aislamiento de red le indica si el código de instalación hace algo sospechoso:

El patrón de dos pasos es importante. El primer paso necesita acceso a la red para llegar a PyPI, por lo que una instalación posterior El guión aún podría filtrarse. Ejecute el paso uno en una máquina virtual limpia, sin secretos y con una regla de salida de DNS que registra cada nombre de host saliente. El paso dos se ejecuta con --network=none; si tu La biblioteca intenta llamar a casa en el momento de la importación, la importación falla y ya lo sabe.

Mejor: use una microVM desechable como Firecracker o orb en macOS para lo mismo forma sin el kernel compartido de Docker. Para JavaScript, el modelo de permisos de Deno le brinda la Mismo aislamiento sin contenedor: deno run --allow-net=api.openai.com,api.anthropic.com agent.ts.

Comprobación 4: verificar la exposición a la infracción antes de rotar

Si sus llaves estaban en una máquina que tocó una mala liberación, gírelas. Sin debate. Pero también comprobar si las identidades vinculadas a esas claves ya aparecen en volcados conocidos; una computadora portátil que ejecutó una versión comprometida de LiteLLM el mes pasado que podría ser una computadora portátil cuyo propietario reutilizó contraseñas de un volcado de la Colección 1 de 2019. Ambos problemas deben solucionarse y la verificación 4 le indica qué cuentas necesitan la atención más urgente.

botoi's /v1/breach/check El punto final incluye las mismas fuentes de datos que la mayoría de IAM empresariales. Las herramientas pagan por puesto y no cuestan nada en el nivel gratuito:

Recorra cada correo electrónico de cuenta de servicio, cada correo electrónico de usuario de máquina y cada desarrollador humano cuya computadora portátil tocó la ventana. Cualquier correo electrónico con password_exposed: true necesita una rotación y un reinicio forzado de MFA antes de continuar. Canalice el resultado en su runbook de respuesta a incidentes; uno curl por identidad, diez minutos para una organización de ingeniería de 50 personas.

Comprobación 5: observe su salida de salida

El malware posterior a la instalación tiene que llamar a casa de alguna manera. La mayoría de los desarrolladores no pueden recordar la última vez. observaron con qué está hablando realmente su computadora portátil; esa es la brecha con la que contaba TeamPCP.

En una máquina sospechosa, un solo comando le dice cuál es cada proceso de Python y Node conectado a:

A nivel de flota, impulse a cada computadora portátil de desarrollador y corredor de CI a través de una salida de Confianza Cero lista de permitidos. Cloudflare WARP, Tailscale ACL y Little Snitch te dan la misma forma: enumere los nombres de host que realmente necesita, bloquee el resto, alerte sobre los bloques.

Una lista de permitidos tan ajustada resulta dura la primera semana. En la segunda semana, las únicas alertas que ve son real: una biblioteca que intenta llegar a un destino al que no tiene por qué llegar. Eso es exactamente lo señal El ladrón de información de TeamPCP se habría disparado durante la instalación.

Los cinco controles de un vistazo

Controlar Esfuerzo Reducción del radio de explosión
Fijar versiones exactas con hashes 1 hora para un único repositorio; 1 día para un monorepo Detiene el lanzamiento silencioso de una versión comprometida
Mover credenciales a sesiones de corta duración De 2 a 4 horas por desarrollador, una sola vez Límites de acceso a entre 8 y 12 horas en lugar de meses
Sandbox en cada instalación 15 minutos por cada nueva evaluación de la biblioteca El código en el momento de la instalación no puede ver secretos reales ni la red de producción
Identidades de verificación de infracciones vinculadas a claves expuestas 10 minutos para una organización de 50 personas Prioriza las rotaciones y los reinicios de MFA por exposición conocida
Aplicar la lista de salida permitida en desarrollo y CI 1 día para configurar, continuo para mantener Bloquea los canales de telefonía residencial que filtran datos robados

Conclusiones clave

  • Fije versiones exactas, no rangos. Un signo de intercalación o una tilde en su archivo de bloqueo es una promesa que la liberación de mañana es segura. TeamPCP rompió esa promesa.
  • Las credenciales de la nube no pertenecen a los shells de desarrollo. Las sesiones SSO de corta duración se convierten en un credencial robada en un evento de rotación, no en una infracción.
  • Sandbox se instala antes de confiar en ellas. Docker con mayúsculas caídas y --network=none es suficiente para detectar malware en el momento de la instalación por el coste de 15 minutos.
  • Rotar más verificación de incumplimiento. Si una máquina tocó un lanzamiento defectuoso, gire cada identidad que vio y ejecutar cada correo electrónico /v1/breach/check para encontrar los que Necesita reinicios urgentes de MFA.
  • Las listas de salida permitidas captan la llamada a casa. Las reglas Zero Trust en computadoras portátiles y CI se convierten en un Exfiltración silenciosa hacia un evento ruidoso, registrado y bloqueable.

Botoi le brinda puntos finales HTTP para verificación de infracciones, verificación de hash, inspección SSL, HTTP auditoría de encabezados y búsqueda de metadatos de npm; Los primitivos que necesitas para auditar una cadena de suministro. incidente sin instalar otra biblioteca más. Una clave API, 5 solicitudes/min en el nivel gratuito, no instalar ganchos. Navega por el documentos interactivos o cablear el servidor MCP en Claude Code o Cursor para llamar a los mismos puntos finales desde su editor mientras trabaja en el lista de verificación.

FAQ

¿Qué versiones de LiteLLM se vieron afectadas y cómo confirmo que estoy limpio?
Los lanzamientos maliciosos surgieron en marzo de 2026 y permanecieron en PyPI el tiempo suficiente para aterrizar en cachés de CI y computadoras portátiles de desarrolladores en todo el mundo. Ejecute pip show litellm para imprimir su versión instalada, luego haga una referencia cruzada de la versión y cargue la marca de tiempo con el aviso de seguridad de LiteLLM y el historial de versiones de PyPI. Si una máquina ejecutó pip install litellm durante la ventana, trátela como comprometida: rote cada clave de nube que se encontraba en ese shell, vuelva a implementarla desde una imagen limpia y borre los tokens ~/.aws, ~/.config/gcloud y ~/.ssh anteriores a la rotación.
¿Fue esto culpa de PyPI o de LiteLLM?
Ambos, y esa es la lección. LiteLLM es una biblioteca legítima con un mantenedor real; el atacante utilizó un canal de liberación comprometido, no un typosquat. PyPI todavía no requiere versiones firmadas ni 2FA obligatoria en los tokens para cada proyecto, por lo que una credencial de carga robada se convierte en malware enviado en minutos. La firma de paquetes a través de Sigstore y tokens con alcance del mantenedor habrían cortado el ataque en el momento de la carga.
¿Debo rotar todas las claves de AWS o solo las que se tocan en las máquinas afectadas?
Gírelos todos. Los atacantes recurren a STS, cadenas de asunción de roles y políticas de confianza entre cuentas en el momento en que tienen una única clave de larga duración. Si la computadora portátil o el ejecutor de CI que vio la versión incorrecta tenía alguna credencial de IAM en la memoria o en el disco, trate todo el gráfico principal al que se puede acceder desde esa identidad como activo. Misma lógica para las cuentas de servicio de GCP y las entidades principales de servicio de Azure.
¿Bun o Deno cambian esto para las herramientas de IA de JavaScript?
Un poco, no mucho. Deno ejecuta código con permisos explícitos (--allow-net, --allow-env), por lo que una biblioteca que de repente intenta leer ~/.aws/credentials se le niega a menos que le haya otorgado acceso al sistema de archivos. Bun tiene un indicador --frozen-lockfile y no ejecuta scripts de instalación de forma predeterminada en versiones recientes. Ambas son mejoras con respecto a los valores predeterminados de npm, pero ninguna impide que una biblioteca extraiga datos una vez que el código de su aplicación le entrega las credenciales en tiempo de ejecución.
¿Qué diferencia el riesgo de la cadena de suministro de la cadena de herramientas de IA del riesgo normal de npm o PyPI?
Las bibliotecas de IA se encuentran inusualmente cerca de los secretos. Un contenedor LLM como LiteLLM necesita claves API para más de 10 proveedores en un archivo env. Un agente de LangChain lee las credenciales de AWS para poder llamar a S3 como herramienta. Un SDK de Claude toca GITHUB_TOKEN porque le pediste que abriera PR. El radio de explosión por instalación es mayor que el de una biblioteca de servicios públicos típica; una versión comprometida le brinda una billetera con claves de proveedor, credenciales de nube y acceso al código fuente de una sola vez.

Empieza a construir con botoi

150+ endpoints de API para consultas, procesamiento de texto, generacion de imagenes y utilidades para desarrolladores. Plan gratuito, sin tarjeta de credito.