El nuevo firewall npm de GitHub bloquea paquetes peligrosos antes de instalarlos
Cada npm install es un pequeño acto de confianza. Una compilación descarga cientos de paquetes de un registro público, ejecuta los scripts de ciclo de vida que traigan y nadie lee el código antes. GitHub ofrece ahora una forma de colocar un punto de control de políticas delante de ese momento: un firewall de paquetes, publicado en vista previa pública, que inspecciona las peticiones de metadatos y las descargas de npm y rechaza todo lo que incumpla las reglas definidas por la empresa.
Qué ha pasado
El firewall está disponible en vista previa pública para los clientes de GitHub Enterprise Cloud, incluidas las implantaciones con residencia de datos. Por ahora solo entiende npm; se espera que otros ecosistemas lleguen más adelante.
A nivel de arquitectura es una puerta situada entre los endpoints o registros internos de la organización y el registro público. Los portátiles de los desarrolladores, los servidores de CI/CD y los agentes autónomos de programación apuntan su gestor de paquetes al firewall en lugar de al registro directamente. Cada petición se contrasta con la política, y las descargas que no la cumplen se bloquean en el momento de la instalación en vez de descubrirse después.
Los administradores deben configurar ellos mismos los controles de política. El conjunto actual cubre cinco comprobaciones:
- Malware conocido. Los paquetes con un aviso de malware activo en la base de datos de avisos de GitHub se rechazan directamente.
- Umbral de severidad. Se bloquean las versiones afectadas por una vulnerabilidad publicada con un nivel igual o superior al elegido. El valor por defecto es "solo Critical", con las opciones "High o superior", "Medium o superior" y "cualquier severidad".
- Degradaciones de atestación. La atestación de procedencia SLSA de la versión solicitada se compara con las versiones anteriores. Si un paquete que antes publicaba procedencia firmada deja de hacerlo de repente, la descarga se detiene. Ese patrón es una señal fuerte de un pipeline de publicación comprometido.
- Scripts de instalación recién introducidos. Se bloquean las versiones que añaden hooks
preinstall,installopostinstalldonde las versiones anteriores no los tenían. Los scripts de instalación ejecutan código arbitrario y siguen siendo el mecanismo favorito para distribuir paquetes que roban credenciales. - Antigüedad mínima del paquete. Un periodo de espera que rechaza las versiones más recientes que un número configurado de días. El rango va de 1 a 365 días, el valor por defecto es un día y ponerlo a cero desactiva la comprobación.
Los desarrolladores que se topen con un falso positivo, o que necesiten de verdad una versión que todavía está dentro del periodo de espera, pueden presentar una solicitud de excepción con un motivo, que los administradores y responsables de seguridad de la empresa aprueban o rechazan.
Por qué importa
El momento de la instalación es donde los ataques modernos a la cadena de suministro realmente triunfan. El patrón típico es el secuestro de la cuenta de un mantenedor seguido de una versión envenenada con un script postinstall que recolecta tokens, claves de nube y ficheros .npmrc a los pocos minutos de publicarse. Cuando el registro retira la versión, miles de compilaciones ya la han ejecutado.
Dos tendencias agravan la ventana. Los runners de CI instalan dependencias en cada ejecución del pipeline sin ninguna persona en el bucle, y los agentes de programación con IA ahora añaden y actualizan paquetes por su cuenta para completar una tarea. Ninguno lee el diff del lockfile antes de descargar una versión que tiene unas pocas horas.
Por eso los periodos de espera se están extendiendo por todos los ecosistemas. Durante el último año npm, PyPI, las extensiones de Visual Studio Code, RubyGems, Bun, pnpm y Yarn han introducido alguna forma de antigüedad mínima de versión. Rust se suma: la versión 1.100, prevista para el 12 de noviembre de 2026, añade una antigüedad mínima de publicación configurable en el fichero de configuración de Cargo, y si no se define nada se aplica por defecto una espera de siete días a las versiones de crates.
Conviene ser honestos con los límites. Un periodo de espera retrasa las correcciones de seguridad legítimas tanto como las maliciosas, salvo que alguien conceda una excepción, y el código malicioso no se vuelve inofensivo con la edad. Una versión que evade los escáneres simplemente sobrevive al periodo de espera. Lo que compra el retraso es tiempo: tiempo para que investigadores, mantenedores y registros detecten y retiren una versión dañina antes de que la siguiente actualización de dependencias la propague.
Qué hacer
- Si usas GitHub Enterprise Cloud, activa la vista previa primero en una organización no crítica, apunta a ella los runners de CI y los agentes de programación, y ajusta el umbral de severidad y el periodo de espera antes de ampliar el despliegue.
- Todos los demás, configurad un periodo de espera de todos modos. La mayoría de los gestores de paquetes principales exponen ya un ajuste de antigüedad mínima de versión. Entre uno y tres días bastan para atrapar la mayoría de las versiones secuestradas sin frenar el ritmo de trabajo.
- Domad los scripts de ciclo de vida. Ejecutad las instalaciones con los scripts desactivados siempre que la pila lo permita y mantened una lista explícita de los pocos paquetes que los necesitan de forma legítima.
- Confirmad y revisad los lockfiles. Tratad un cambio de lockfile como un cambio de código, sobre todo cuando lo haya generado un agente automático. Una nueva dependencia transitiva o un salto a una versión de hace unas horas merece una segunda mirada.
- Reducid lo que puede robar un script malicioso. Usad tokens de registro de corta duración y solo lectura, y credenciales de nube con alcance limitado en los servidores de compilación, y nunca dejéis secretos de larga duración en variables de entorno que un hook de instalación pueda leer.
- Vigilad las señales de procedencia. Una versión que pierde su atestación o gana un script de instalación es motivo para parar, no una curiosidad.
Los manifiestos de dependencias, los diffs de lockfile, los scripts de ciclo de vida y la procedencia de lo que descarga una compilación son exactamente la capa que examina la revisión de código asistida por IA de nuestro equipo, de modo que un paquete sospechoso se señala mientras todavía es un pull request y no después de ejecutarse en un runner de producción.
