Portada de UrsaKit para la guía de verificar paquetes sugeridos por asistentes de IA

Pídele a un asistente de IA una utilidad pequeña y a menudo responderá con un import seguro de sí mismo y un comando de instalación. A veces el paquete no existe. No es ruido aleatorio: los mismos nombres inventados aparecen una y otra vez en prompts repetidos, que es justo la propiedad que un atacante necesita para registrar un nombre por adelantado y esperar.

Ese ataque se llama slopsquatting, y la defensa no es «deja de usar asistentes de IA». Es verificar el nombre antes de que llegue a tu gestor de paquetes y hacer que la instalación sea más difícil de weaponizar.

01Qué es realmente el slopsquatting

El patrón tiene tres partes. Un modelo produce un nombre de paquete plausible. Ese nombre es lo bastante estable para ser predecible entre usuarios y ejecuciones. Un registro permite a cualquiera reclamar un nombre no usado.

Los estudios sobre modelos que generan código sitúan las recomendaciones alucinadas en torno a uno de cada cinco paquetes sugeridos. El typosquatting de nombres duplicados explota a un humano que teclea mal un paquete conocido; el slopsquatting explota a una máquina que inventa uno con confianza. Como el modelo presenta su sugerencia con el mismo tono que usa para una librería real, el error se copia fácilmente a una terminal sin pensarlo dos veces.

Que exista no es lo mismo que ser legítimo

Un atacante puede registrar un nombre alucinado después de que aparezca en la salida de un modelo. Que npm lo encuentre solo prueba que alguien reclamó el nombre: no que el código sea seguro ni que sea el que el modelo quería decir.

02Por qué los nombres alucinados son predecibles

Los modelos generan nombres como generan cualquier otro token: continuando el patrón más plausible. Para una librería de fechas, concatenar date con un sufijo común; para una utilidad de CLI, @scope/tool-name. La salida no es el paquete real, pero se parece exactamente a uno.

Como la decodificación se guía por las mismas estadísticas cada vez, el mismo prompt tiende a producir el mismo nombre inventado. Esa previsibilidad es la vulnerabilidad. También significa que la solución no puede ser «usa un prompt mejor»: no existe un modelo que nunca alucine un nombre, así que la verificación tiene que vivir en tu flujo de trabajo.

03Verifica un nombre antes de instalarlo

Convierte esto en un reflejo y toda la clase de ataque se vuelve mucho más difícil.

  1. Pregunta directamente al registro. Un 404 termina la conversación.
npm view left-pad version repository.url maintainers time.created
# version = '1.3.0'
# repository.url = 'git+ssh://git@github.com/stevemao/left-pad.git'

npm view left-paad version
# npm error 404 Not Found - GET https://registry.npmjs.org/left-paad - Not found
python3 -m pip index versions requests
# requests (2.32.5)
# Available versions: 2.32.5, 2.32.4, 2.32.3, ...
  1. Empareja el paquete con el proyecto que esperas. Lee repository.url y la lista de mantenedores. Una librería con repositorio de código, changelog y años de releases se ve distinta de un nombre registrado la semana pasada sin página de inicio.
  2. Revisa la forma del historial de releases. Un paquete cuya lista completa de versiones apareció en un solo día es una señal de alarma, igual que una versión rara como 99.0.0 elegida para parecer maduro.
  3. Compara la sugerencia con lo que el ecosistema usa de verdad. Si el asistente propone un envoltorio para una librería conocida, comprueba si esa librería ya expone la función de forma nativa. Las alucinaciones a menudo existen para llenar un hueco que no existe.

04Lockfiles, scripts de instalación y la trampa de ejecución

Instalar un paquete no es una acción de solo lectura. Los scripts de ciclo de vida se ejecutan al instalar, y un paquete malicioso puede usarlos para ejecutar código antes de que tus tests lleguen a correr.

  • Confirma y revisa los lockfiles. npm ci instala exactamente lo que fija el lockfile, así que un lockfile revisado es un control. Un npm install <typo> sin revisar lo reescribe.
  • Omite los scripts en el primer contacto. Añade una dependencia con npm install --ignore-scripts, inspecciónala y luego instala con normalidad si confías en ella.
  • Usa instalación fijada por hash en Python. pip install --require-hashes -r requirements.txt rechaza un paquete cuyos bytes difieren del hash registrado.
  • Mantén un paso de revisión en la instalación. El diff del lockfile en la revisión de código es uno de los sitios más baratos para notar un nombre que no pertenece ahí.
npm ci --ignore-scripts
npm ls --all | head -40
git diff -- package.json package-lock.json

Compara el lockfile, no solo package.json

Una nueva dependencia de primer nivel suele arrastrar una docena de paquetes transitivos. El diff del lockfile los muestra todos, y ahí aparecerá un nombre que nunca aprobaste.

05Blinda el flujo, no solo el momento

Las comprobaciones individuales atrapan errores individuales. Unos pocos controles estructurales atrapan la clase entera.

ControlQué detiene
Proxy de registro privado con lista permitidaLos nombres desconocidos no llegan a los desarrolladores
Revisión obligatoria del lockfileDependencias transitivas coladas
Scripts de ciclo de vida desactivados en CIEjecución de código al instalar
Escaneo de dependencias en CIPaquetes maliciosos conocidos y CVE
Reglas de nombres de paquetes internosConfusión entre scopes internos y públicos
Comprobación de procedencia / atestaciónTyposquats sin pipeline de build real

El proxy de registro es el de mayor palanca: si un paquete no está ya espejado o permitido, la instalación falla y un humano decide. Eso convierte un riesgo silencioso de cadena de suministro en una revisión rutinaria.

06Si ya instalaste el paquete equivocado

Trátalo como un incidente, no como una errata. Elimina la dependencia y luego revisa qué hizo realmente la instalación: inspecciona los scripts postinstall y preinstall en node_modules/<name>, busca nuevas llamadas de red salientes, rota cualquier credencial presente en el entorno durante la instalación y comprueba si el lockfile se confirmó y se subió. En un repositorio compartido, el lockfile comprometido es la parte que se propaga.

07Errores comunes y soluciones

ErrorPor qué fallaSolución
Instalar directo desde la respuesta del chatNo se comprueba el registroEjecuta npm view o pip index versions primero
Confiar en un paquete porque existeLos atacantes registran nombres alucinadosRevisa publicador, repo e historial de releases
Revisar solo package.jsonLos paquetes transitivos se esconden ahíRevisa el diff del lockfile
Dejar que CI ejecute scripts de instalaciónEl código malicioso se ejecuta durante el buildUsa --ignore-scripts o aísla la instalación
Asumir que un nombre con scope es internoLos scopes públicos pueden parecer internosExige un scope interno explícito

El hábito que importa es pequeño: nunca dejes que la sugerencia de un modelo se convierta en dependencia sin una consulta al registro. El resto del blindaje existe para las veces en que estás cansado, con prisa y listo para confiar en la salida.

Preguntas frecuentes

¿Qué es el slopsquatting?

El slopsquatting es registrar un nombre de paquete que un modelo de IA inventa, para que el siguiente desarrollador que copie la sugerencia instale el código del atacante en lugar de nada.

¿De verdad los asistentes de IA inventan nombres de paquete?

Sí. Estudios sobre modelos que generan código encontraron que cerca de uno de cada cinco paquetes recomendados no existía en el registro, y que los mismos nombres inventados se repiten en prompts sucesivos.

¿Es seguro si el paquete existe en npm?

Que exista es necesario pero no suficiente. Un nombre puede existir porque un atacante lo registró tras verlo alucinado, así que revisa también el publicador, el enlace al repositorio, la antigüedad y el patrón de descargas.

¿Cuál es la forma más rápida de comprobar un paquete?

Pregúntale directamente al registro antes de instalar. En npm es `npm view <name>`; en Python, `python -m pip index versions <name>`. Un 404 es una señal de parada.

¿Debería desactivar los scripts de instalación?

Para dependencias no confiables o recién añadidas, sí. `npm install --ignore-scripts` omite los scripts de ciclo de vida, una vía habitual de ejecución en paquetes maliciosos; instala con normalidad cuando la dependencia esté revisada.

Volver a los artículos

Artículos relacionados

Herramientas relacionadas