Ahora, ¿cómo lo evitás?
Primero: entendé que tu software no es tuyo si no sabés con qué lo hiciste. Ahí entra el SBOM (Software Bill of Materials). No es compliance, es defensa. Es saber exactamente qué metiste en cada build, qué versión, con qué hash, de dónde vino, y cuándo se usó. Y si no lo firmás, no sirve. Si no lo vinculás al artefacto, no sirve. Si no lo generás en el build, no sirve. Porque la única verdad es la que se produce en el momento de la compilación.
Yo uso Syft, CycloneDX y cosign en cada pipeline. Y si falla la generación del SBOM, falla la build. Sin excepciones. ¿Por qué? Porque no podés defender lo que no podés ver.
Después viene la parte crítica: firmar todo. Código, artefactos, metadatos. Usá SLSA, sigstore, in-toto, lo que funcione con tu stack. La idea es una sola: nadie debería poder meter código en producción sin trazabilidad y sin procedencia verificable.
Tercero: el código fuente no se toca sin revisión. Usá ramas protegidas, pull requests con múltiples aprobaciones, análisis estático, herramientas como Legitify, y nunca, pero nunca, metas secretos al repo. Cada dev es una puerta. Su IDE, sus plugins, sus configuraciones. Asegurá esa puerta.
Cuarto: las dependencias son tu responsabilidad. No me importa si el bug es de otro. Si lo tenés en tu proyecto, es tuyo. Escaneá con OWASP Dependency-Check, Snyk, OSV, Grype, y después hacé triaje con VEX. No todo CVE rompe la build, pero todo CVE se analiza. Si no hay parche, parcheás vos. Si el proveedor no responde, lo forkeás. Si es transitive, lo aislás. Y si no podés, lo envolvés. Así se hace seguridad en serio.
Quinto: tu build es el punto de control total. Aislado, reproducible, versionado, con imágenes verificadas. No aceptes compilaciones que no podés replicar. Si usás GitHub Actions, firmá todo. Si tenés runners propios, que sean efímeros. Y nada se recicla: ni cache, ni variables, ni contenedores. Porque donde hay estado compartido, hay vector de ataque.
Sexto: escaneá tus artefactos antes de ejecutar. El binario final puede traer código que nunca viste en el código fuente. Y si lo firmaste mal, o usaste un compilador contaminado, te lo comiste igual. Usá análisis de composición binaria, SBOM enriquecidos, validación de firmas y políticas de autorización. Nada se despliega sin verificación.
Y por último: automatizá todo. Desde la generación del SBOM hasta el escaneo y la remediación. Porque si dependés de humanos para esto, ya perdiste. Necesitás pipelines inteligentes, alertas en tiempo real, métricas, dashboards, trazabilidad y respuesta coordinada. Y necesitás cultura. Equipos que entiendan que cada decisión en el código impacta en la cadena.