Saltar al contenido
Categoria: Endurecimiento9 min de lectura

Supply Chain Security: Firma con Sigstore y SBOM Real en CI/CD

Por Lucas Andrade ·

Como Basilisk implementa cosign, SLSA y CycloneDX en pipelines reales para mitigar ataques tipo SolarWinds, XZ Utils y dependency confusion.

Supply Chain Security: Firma con Sigstore y SBOM Real en CI/CD

Cuando la puerta trasera de XZ Utils (CVE-2024-3094) estuvo a punto de entrar en distribuciones Linux estables en marzo de 2024, quedo claro que firmar un tag en GitHub ya no alcanza. La cadena de suministro de software se volvio objetivo prioritario porque un solo maintainer comprometido propaga codigo malicioso a millones de hosts en horas. En Basilisk OffSec trabajamos ambos lados: simulamos ataques contra pipelines de clientes y ayudamos a equipos a cerrar las puertas que encontramos. Este post consolida lo que aplicamos en CI/CD real usando Sigstore cosign, SLSA nivel 3 y SBOMs CycloneDX, con enfoque pragmatico y no teatro de cumplimiento.

Por que la cadena de suministro se volvio el objetivo

Un atacante tiene dos caminos a tu produccion: la puerta del frente (atacar tus servicios expuestos) o la puerta trasera (comprometer algo en lo que ya confias). La puerta trasera escala mejor. El incidente de SolarWinds mostro que un proceso de build manipulado golpea 18.000 organizaciones de una vez. XZ mostro que un atacante paciente gana confianza social a lo largo de dos anos, obtiene derechos de maintainer y planta una backdoor que solo dispara bajo condiciones muy especificas.

El denominador comun: el eslabon mas debil nunca es la criptografia, es la cadena humana y de proceso alrededor del build. Por eso la respuesta no es una sola tecnologia sino una cadena de firma (quien lo construyo), procedencia (como y donde se construyo) e inventario (que hay adentro). Si falta un eslabon, volas a ciegas. El incidente de CodeCov en 2021, donde una credencial filtrada manipulo un script uploader de bash, fue el llamado de atencion para la capa de firma.

Cosign keyless: Fulcio y Rekor

El primer paso es abandonar la idea de clave privada de larga duracion guardada en un secret manager. cosign keyless usa OIDC de GitHub Actions, GitLab CI o Buildkite para emitir un certificado efimero via Fulcio, valido 10 minutos, y registra la firma en Rekor, un log transparente append-only. Eso elimina toda una categoria de fugas de clave de firma. Un workflow tipico tiene tres jobs: build reproducible, sign con cosign sign --yes y attest con predicado SLSA Provenance v1.0.

La clave del log transparente: aun si un atacante obtiene brevemente una identidad OIDC valida, toda firma queda registrada de forma publica e inmutable. Podes preguntar retroactivamente que artefactos se firmaron con que identidad y en que momento, y cazar anomalias. En proyectos de cliente vimos 90% menos tiempo de rotacion de credenciales al migrar de claves PGP a keyless, y eso conecta directamente con lo que discutimos en AppSec Shift-Left: SAST, SCA y Escaneo de Secretos sin Frenar al Equipo.

SBOM con Syft y CycloneDX

Un SBOM no es un XML que nadie lee. Generamos CycloneDX 1.6 con syft en el momento del build, incluyendo hashes SHA-256 de cada componente, licencia SPDX y proveedor. Una invocacion real: syft packages dir:. -o cyclonedx-json=sbom.json. El archivo viaja junto a la imagen OCI como artefacto referenciado, atado a la imagen con cosign attest --predicate sbom.json --type cyclonedx, no perdido en un S3 que nadie encontrara en seis meses.

El valor de un SBOM aparece el dia del proximo zero-day. Cuando una CVE critica surge en una dependencia transitiva, la pregunta no es abstracta sino operativa: cuales de nuestras 200 imagenes en ejecucion contienen la version vulnerable? Sin SBOM eso es arqueologia de varios dias. Con un inventario SBOM consultable es una query de minutos. Por eso exactamente atas el SBOM al artefacto y no a una pagina de wiki.

Escaneo con Grype y Policy-as-Code

Para validar corremos grype en el pull request y tambien en background contra el registry, porque las CVE nuevas aparecen despues del merge. Una imagen que estaba limpia ayer puede cargar una vulnerabilidad critica hoy sin que cambie una sola linea de codigo. Combinamos esto con policy-as-code via Kyverno o Conftest, bloqueando despliegues si el SBOM tiene una dependencia con CVSS superior a 7.0 sin excepcion documentada.

El mecanismo de excepcion importa. Una policy dura sin camino de excepcion documentado se saltea apenas bloquea un deploy urgente, y ahi muere. Usamos un archivo VEX (Vulnerability Exploitability eXchange) para declarar que una CVE dada no es explotable en el contexto especifico, con justificacion y fecha de vencimiento. Este mismo modelo de policy aparece cuando discutimos Hardening de Linux Server: CIS Benchmark Aplicado sin Romper Produccion en servidores de produccion.

Entender los niveles de SLSA

SLSA (Supply-chain Levels for Software Artifacts) se volvio el marco de referencia despues de que Google y OpenSSF estandarizaron la v1.0 en 2023. Nivel 1 es solo tener build script versionado. Nivel 2 exige builder hospedado con procedencia firmada. Nivel 3, donde queremos llegar en proyectos sensibles, exige aislamiento del build, procedencia no falsificable y hermetic builds donde el build no tiene acceso de red no controlado.

El salto decisivo esta entre Nivel 2 y 3: una procedencia que el propio builder genera y firma no puede ser falsificada por un desarrollador comprometido, porque no controla el proceso del builder. Para equipos que tambien atienden Dependency Confusion y Typosquatting: Defensa Practica para Equipos Dev, SLSA cierra el lado del publisher, mientras la reserva de namespace y el pinning de registry cubren el lado del consumidor.

Procedencia con slsa-github-generator

En la practica usamos GitHub Actions con el reusable workflow slsa-framework/slsa-github-generator, que produce attestation in-toto firmada por el propio runner via OIDC. Esa attestation documenta de forma criptograficamente verificable el commit fuente, los parametros de build y la version de la toolchain. Un atacante que comprometa a un maintainer todavia tiene que romper el builder de GitHub, lo que eleva el costo del ataque en ordenes de magnitud.

El punto de quiebre mas comun aca son los builds no reproducibles. Timestamps incrustados en binarios Go, rutas absolutas e IDs de build embebidos hacen que dos builds del mismo commit produzcan hashes distintos. Usa -trimpath, fija SOURCE_DATE_EPOCH y pinea la toolchain en un lockfile, si no tu procedencia esta firmada pero no es reproducible de forma verificable.

Verificacion del lado del consumidor

Verificar en el consumidor es tan importante como firmar en el productor. En clusters Kubernetes usamos el admission controller policy-controller de Sigstore con ClusterImagePolicy exigiendo que toda imagen en namespace produccion tenga firma cosign valida, identidad OIDC del dominio basilisk.example y attestation SLSA del builder esperado. Configuramos soft-fail en staging para no romper deploys de emergencia, y hard-fail en prod.

Tambien corremos cosign verify-blob en los binarios CLI bajados a estaciones de analista, integrado al flujo descrito en OPSEC para Investigadores de Seguridad: Modelo de Amenaza Personal, porque el equipo de OffSec descarga muchas herramientas de origen incierto y eso se vuelve vector obvio. El principio: firma en el origen, verifica en el punto de consumo, y nunca confies en un artefacto solo porque esta en tu registry.

Limites: takeover social y Scorecard

Donde se rompe en la practica: builds no reproducibles, timestamps incrustados en binarios Go, dependencias transitivas que cambian entre git pull y CI, y maintainers que rechazan adoptar 2FA. El XZ pre-2.0 ya tenia senales de takeover social del proyecto que ninguna firma captura: un contribuidor nuevo que gana confianza sospechosamente rapido, presion sobre el maintainer original, y commits con datos de test ofuscados.

Por eso recomendamos combinar cosign+SLSA+SBOM con revision periodica de maintainers criticos, scorecard de OpenSSF corriendo semanalmente sobre las top 50 dependencias, y ejercicios de red team que simulen compromiso de maintainer, similar a lo que hacemos en engagements descritos en Adversary Emulation con Caldera y MITRE ATT&CK en Laboratorio Corporativo y Purple Team en la Practica: Construyendo Ciclo de Feedback Red vs Blue. Tecnologia sin proceso de mantenimiento se vuelve teatro caro.

Pinning de registry y digests inmutables

Firma y procedencia sirven de poco si tus deploys referencian un tag movil como :latest. Un :latest verificado ayer puede apuntar a otra imagen hoy. En produccion, pinea siempre al digest inmutable (image@sha256:...), no a un tag. El digest es la huella criptografica del contenido exacto de la imagen; un digest pineado mas firma verificada dan una cadena sin cortes desde el commit fuente hasta el contenedor en ejecucion.

Complementa eso con un registry interno espejado (Harbor, Artifactory) corriendo un pull-through cache con reglas de inmutabilidad, para que un tag upstream borrado o sobreescrito no rompa tus builds y un atacante no pueda re-atar un tag ya verificado. Combinado con una allowlist de registries permitidos en el admission controller, cierras la brecha por donde se cuelan los ataques de dependency confusion.

Rollout de 30 dias

Esta semana: agrega cosign sign keyless en un pipeline unico, genera SBOM CycloneDX con syft y publicalo como artefacto OCI junto a la imagen. La proxima semana: activa grype en el PR con policy warn-only para calibrar tu ruido base de CVE. Semana tres: activa cosign verify obligatorio en un namespace de staging con soft-fail. Semana cuatro: pasa a hard-fail en prod para un unico servicio bien entendido y expande desde ahi.

FAQ

Keyless requiere acceso a internet en el build? Si, Fulcio y Rekor son servicios online. Para ambientes air-gapped corres una instancia privada de Sigstore (Fulcio, Rekor, Trillian) internamente o volves a cosign basado en clave con una key en un KMS/HSM. Keyless es la recomendacion por defecto, no un dogma.

Un SBOM reemplaza el escaneo de vulnerabilidades? No. El SBOM es el inventario, el scanner es el analisis contra el. Un SBOM sin rescaneo continuo contra feeds de CVE actuales envejece en dias. Juntos dan una foto consultable y actual de tu superficie de ataque; solos son medias medidas.

Como vendes el costo a la gerencia? No con argumentos de compliance sino con la cuenta de tiempo de respuesta. Durante la ultima CVE grande de OpenSSL, los equipos sin inventario SBOM tardaron dias en promedio solo en descubrir que sistemas estaban afectados. Los equipos con SBOM atado respondieron la misma pregunta en minutos y empezaron a parchear de inmediato. Esa diferencia se traduce directo en riesgo de caida y horas extra, y eso es exactamente lo que entiende un dueno de presupuesto.

Takeaway practico: empieza pequeno y medible. En 30 dias tienes base para exigir SLSA L2 a proveedores y responder con evidencia cuando ocurra el proximo XZ, porque va a ocurrir. El costo de implementacion en un pipeline existente ronda 2 a 4 horas de ingeniero; el costo de no implementar es preguntar a tus clientes en una call de domingo si firmaste ese contenedor que esta minando Monero en produccion.

Related posts

Nenhum comentário ainda

Seja o primeiro a comentar.

Deixe seu comentário

Entre com sua conta Canverly para comentar. Você pode usar a mesma conta em qualquer site da rede.

Entrar com Canverly