Nuestra opinión es que el código abierto no tiene realmente un problema de seguridad, sino de distribución. En el artículo de hoy vamos a ver este tema en detalle y queremos analizar cual es la situación del código Open Source en la comunidad IT y qué problemas podemos encontrar a la hora de apoyarnos en soluciones de código abierto.
Frank Crane no se refería al código open source cuando dijo su célebre frase: «Puedes ser engañado si confías demasiado, pero vivirás atormentado si no confías lo suficiente». Sin embargo, esta frase resume de manera muy clara la brecha que existe entre cómo se están utilizando los recursos de código abierto y los patrones de confianza cero que las empresas están tratando de implementar en sus prácticas de DevSecOps.
Bonita palabra, pero ¿y qué significa DevSecOps?
Empecemos por el principio, «DevSecOps» es un término que combina tres conceptos clave en el desarrollo de software: «Desarrollo» (Development), «Seguridad» (Security) y «Operaciones» (Operations). Por lo que cuando hablamos de «prácticas de DevSecOps» nos referimos a la integración de prácticas de seguridad en todas las etapas del ciclo de vida del desarrollo de software, desde la planificación y el diseño hasta la implementación y el mantenimiento.
En pocas palabras, DevSecOps es una filosofía y una práctica que busca integrar la seguridad directamente en el proceso de desarrollo de software. Esto implica la colaboración entre los equipos de desarrollo de software y seguridad para identificar las vulnerabilidades desde el inicio del proceso de desarrollo. Así se pueden abordar de manera integral y evitar cualquier potencial vulnerabilidad o imprevisto futuro que pueda suponer una brecha de seguridad en la empresa.
Y a día de hoy, ¿cuánto código abierto podemos encontrar?
La mayor parte de los estudios sugieren que entre el 90% y el 98% del software que hay en el mundo es de código abierto. Por lo que podemos asumir que en general a la hora de desarrollar estamos casi siempre utilizando código escrito por otras personas. De esta forma nos encontramos en una situación algo particular, ya que estamos construyendo y modificando estructuras de código confiando implícitamente en todos los programadores que nos han precedido.
Antes de siquiera comenzar a escribir nuestro código, ya estamos confiando en que el código open source subyacente que se encuentra en nuestro sistema se ha escrito de forma segura. Por lo que podemos inferir en que si lo usamos, confiamos en que sus autores no fueron maliciosos y que el código no contiene ningún riesgo para nuestros equipos y sistemas. No olvidemos que detrás de cada gran marca o creador siempre hay un equipo y el código abierto no suele ser nunca producto de un solo autor, sino que suele tener siempre arreglos, mejoras, actualizaciones y fragmentos añadidos por distintos miembros de la comunidad.
Por lo que si el desarrollo de software parte de esta premisa y hace uso de estos recursos, ya podemos partir de que nos encontramos en el lado opuesto a lo que sería la confianza cero. Y si nos encontramos en el lado opuesto a la confianza cero, eso significa que nos encontramos en un grado mucho mas cercano a lo que podríamos llamar la confianza máxima.
Vamos a ver cómo ha evolucionado el software de código abierto
Para saber en qué punto nos encontramos es importante echar la mirada atrás y ver cómo hemos llegado hasta aquí. por lo que vamos a echar un vistazo a la evolución de la distribución de software y quizás así poder determinar con cierto criterio dónde es necesario plantar nuevas raíces de confianza para respaldar las próximas décadas de innovación y que estas puedan seguir basándose en software de código abierto.
En los primeros días, los detractores del código abierto generaron mucho miedo, incertidumbre y duda en torno a su seguridad. Su argumento principal era que el código fuente del software de un propietario estaba más protegido y no daba lugar a que terceros pudieran conocer los entresijos y posibles vulnerabilidades, por lo tanto, se puede entender que es más seguro que cualquier código abierto, cuyo código fuente está disponible para cualquiera y esta exposición da lugar a una posible mayor vulnerabilidad.
Entonces, ¿qué tiene de positivo el open source?
Sin embargo, el paso del tiempo ha demostrado que el software de código abierto y su transparencia también tienen un impacto muy positivo en sus propios sistemas, ya que como bien dice el refrán: «cuatro ojos ven más que dos», esta máxima también aplica a los sistemas de código abierto. El hecho de tener a tantos programadores accediendo, revisando y analizando un código revela vulnerabilidades mucho más rápido y crea soluciones o ciclos de mejora a una velocidad mucho mayor que en entornos donde el código se encuentra protegido y fuera del alcance de una amplia comunidad.
De hecho, más allá del análisis cualitativo o las conclusiones que cada uno pueda sacar, si miramos los resultados estos hablan por sí mismos: el 90% de las vulnerabilidades conocidas (en la lista CVE mantenida por CISA) son de software propietario, a pesar de que alrededor del 97% de todo el software es de código abierto como hemos comentado previamente y se puede ver en este estudio.
Es demasiado fácil desacreditar el estado general de la seguridad del código abierto cuando se encuentra una vulnerabilidad importante de un sistema que esté abierto a la comunidad y se pueda usar de manera global. Pero lejos de ser un problema, muchas de las vulnerabilidades que podemos encontrar y compartir, también se van a reforzar y arreglar de manera extremadamente ágil. Esto demuestra también el alto nivel de seguridad que ofrecen los sistemas de código abierto y que tantas personas lo puedan ver.
¿Caso de éxito, o fracaso? El caso Log4shell
Log4shell, por ejemplo, fue el peor escenario posible para una vulnerabilidad de OSS en términos de escala y visibilidad: esta era una de las bibliotecas más utilizadas en uno de los lenguajes de programación más utilizados. De hecho, vamos a compartir un dato curioso, y es que Log4j incluso estaba funcionando en Marte, por lo que técnicamente podemos decir que esta fue ¡la primera vulnerabilidad de OSS intergaláctica!
La vulnerabilidad de Log4shell era muy fácil de explotar, estaba increíblemente extendida y tenia con consecuencias claramente graves. Sin embargo, los encargados de su mantenimiento pudieron detectar esto, parchearlo y lanzar una nueva versión en cuestión de días. Haciendo así que una posible catástrofe informática basada en el software de código abierto, se tornara en una nueva victoria para la seguridad de sistemas open source. Si tienes curiosidad sobre este hito puedes echar un vistazo por internet y leer más sobre él en detalle, este fue un gran logro dentro de la comunidad open source y fue ampliamente reconocido.
Ahora comparemos el tiempo de detección, divulgación y corrección que podemos encontrarnos cuando se trata de un sistema cuyo desarrollo no es de código abierto, sino que está en manos de proveedores de firmware o cloud privados. En contraposición, podemos encontrar que este tipo de servicios tardan una media de 30, 60 o incluso 90 días en implementar correcciones para algo así en el mejor de los casos. Según un informe reciente de Veracode, más de uno de cada tres, o dicho de otra forma, el 38% de las aplicaciones privadas que se ejecutan con Log4j siguen utilizando versiones vulnerables del programa aunque la comunidad ya haya arreglado este problema hace tiempo.
El software open source requiere de confianza
Cuando comienzas a construir un sistema de software, muchas veces tu proyecto es solo la punta del iceberg. Es decir, muy seguramente no estés desarrollando algo de cero, sino que estés programando en la superficie de millones de líneas de software gratuito que se ha distribuido de manera gratuita y global para hacer un bien común y cuidar del ecosistema IT. En cualquier caso, todo esto solo es posible gracias a la confianza, ya que sin ella nadie usaría estos recursos y por ende no tendrían ningún valor ni recorrido.
Las distribuciones de Linux, además de manejar la compilación del código fuente y evitar que los usuarios de OSS tengan que compilar y depurar, deberían de recibir mucho más reconocimiento ya que desempeñó un papel enorme a la hora de establecer esa confianza. Cuando usas binarios de una distribución de Linux, estás confiando tanto en los responsables del mantenimiento del código como en sus distribuidores. Y esto ya no es solo una capa de confianza, sino dos, porque no dependes solo de un conjunto de personas, sino de dos conjuntos de personas diferentes.
Las distribuciones de Linux entendieron esto a la perfección y realmente avanzaron en el estado del arte de la seguridad de software durante las últimas décadas. Han tenido enfoque pioneros para asegurar las cadenas de suministro de software y han establecido métodos de evaluación muy estrictos para garantizar la calidad de los paquetes que ofrecen, así como de la calidad de sus responsables de mantenimiento.
La importancia de la innovación, caso Debian
Debian es uno de los sistemas operativos más notables en el campo por su sofisticación en la codificación de confianza dentro de la distribución open source. Esto se debe a que Debian utiliza el sistema de firma de clave PGP, donde solo si suficientes profesionales de confianza para su código firman las claves para eventos de encriptación, estos se agregan al anillo de claves de Debian.
Estas firmas se verifican cuando se cargan nuevos paquetes, y luego la distribución de Debian misma vuelve a firmar todos los paquetes que se han integrado. Solo entonces es cuando se publican desde Debian estas nuevas releases, y los usuarios pueden verificar esas firmas sin importar dónde se encuentren esos paquetes y asegurarse así de que esos paquetes provengan de una distribución Debian y de responsables de confianza, asegurando así que los paquetes no han sido alterados por el camino.
Es un modelo que ha funcionado extraordinariamente bien y que otros muchos sistemas de software open source han replicado dados sus buenos resultados.
Sin embargo, las dependencias OSS han superado los modelos de confianza
Hoy en día, la mayoría del consumo de software ocurre fuera de las distribuciones. Los gestores de paquetes de lenguajes de programación —npm (JavaScript), pip (Python), Ruby Gems (Ruby), composer (PHP)— se asemejan a los gestores de paquetes de distribuciones de Linux, pero funcionan de manera ligeramente diferente. Básicamente, ofrecen cero curación: cualquiera puede cargar un paquete y hacerse pasar por unos de los programadores oficiales de cada software. ¿Y entonces cómo sabes en qué confiar? Es muy complejo poder estar seguros de que la instalación de un solo paquete que a continuación va a proceder a instalar varios paquetes de docenas de otras personas aleatorias no sea malicioso o contenga un código que esté al 100% en buen estado.
Docker acrecentó con sus avances aún más este problema de confianza transitiva, ya que las imágenes son muy fáciles de construir porque utilizan gestores de paquetes existentes dentro de ellas mismas. Es decir, puedes usar un «npm install» para obtener paquetes de npm y luego empaquetarlo todo en una imagen de Docker.
Esto te permite llevar a cabo la instalación de una aplicación con los gestores de paquetes de cualquier lenguaje, y luego enviarlo como un gran archivo TAR. Docker reconoció esta brecha de confianza e intentó cerrarla con algo llamado «Verificación de Builds». Este parche de seguridad más tarde evolucionó y se convirtió en una característica que podemos encontrar dentro de Docker Hub.
Docker y las builds verificadas
Estas «Docker Verified Builds» se convirtieron en una forma segura para que los usuarios pudieran especificar el script de construcción para una imagen de Docker en forma de Dockerfile, en un repositorio de código open source. De esta forma, un programador podría escribir el Dockerfile, pero luego Docker encargarse de hacer la construcción, para que así se pueda llegar a ver el código original de los creadores en la imagen que se crea. Docker implementó esto hace años y sigue mejorándolo, así que es importante mencionarlo y darle el crédito que se merece.
Sin embargo, Docker no es el único protagonista de esta historia de creadores de redes de confianza para el software cloud open source; aquí es donde todo se vuelve un poco más complicado. Y es que si entramos al detalle, hay una capa encima de Docker llamada Helm que se usa comúnmente en el ámbito de Kubernetes. Esta capa permite empaquetar un montón de imágenes de Docker y configuración, por lo que lo podemos entender que es un paquete de paquetes.
Veamos un caso aplicado con Helm
Vamos a algo práctico, si instalas el chart de Helm para Prometheus, por ejemplo, es probable que también obtengas un montón de otras imágenes de proyectos personales aleatorios. Osea, puedes estar seguro de que vas a obtener «Prometheus» de los programadores originales de Prometheus, porque el hub de artefactos muestra que proviene de un editor verificado, pero Prometheus a menudo tiene dependencias que no provienen de editores verificados.
El Repositorio Oficial de Charts de Helm, mantenido por los creadores originales de Helm, fue un intento de mejorar la confianza que tenía la comunidad en este tipo de imágenes. Tenía el potencial de brindar a las aplicaciones nativas de la nube el mismo tipo de curación de seguridad proporcionada por las distribuciones de Linux. Pero desafortunadamente resultó ser demasiado difícil de escalar, y acabó convirtiéndose en un modelo con un funcionamiento más similar al de los gestores de paquetes de lenguajes de programación, donde cada proyecto mantiene sus propios charts de Helm.
Todas estas capas de dependencias transitivas son lo que conforma una parte importante del problema de seguridad de la cadena de suministro de software moderna y una de las áreas más jugosas para los hackers o programadores maliciosos. Esta es la primera línea de la nueva batalla para preservar toda la gran confianza en el código abierto que se ha construido a lo largo de las décadas.
Haciendo software seguro desde el principio
La distribución de software a día de hoy se hace de una forma muy diferente a como se distribuía hace 20 años. Antes la forma de hacer llegar software a prácticamente cualquier parte, era mediante cajas físicas en una tienda de informática y cuando comprabas dicha caja sabías perfectamente lo que estabas recibiendo. Sabías de qué empresa venía, que personas habían trabajado en ello y si había sido manipulado o no.
A medida que la distribución de software pasó de los CD-ROM a internet, las distribuciones de Linux resultaron ser asombrosamente exitosas al proporcionar esa confianza en el código de un tercero bajo un ecosistema de trabajo abierto.
Cuando Log4j y SolarWinds mostraron algunas de las vulnerabilidades que se podían explotar realizando ataques a la cadena de suministro de software, los equipos IT comenzaron a asegurar los sistemas de construcción, utilizando marcos como SSDF y SLSA, y verificando las firmas de software producidas por Sigstore (que es ahora el método de firma de software predeterminado utilizado por Kubernetes y todos los registros de lenguajes de programación principales). Aquí podemos ver un claro ejemplo de a lo que podemos llamar progreso.
¿Qué es lo que queda por hacer entonces?
Poder dominar lo que es la seguridad del código open source ha sido un camino bastante complicado de recorrder y sigue siendo algo muy complejo. No olvidemos que estamos hablando de modelos de confianza que tienen décadas de antigüedad y de más de 372 millones de repositorios de código (solo en GitHub).
Todavía hay una gran desconexión entre los CVE conocidos y los desarrolladores que reinstalan código sin saberlo a través de dependencias transitivas. Todavía hay toda una clase de vulnerabilidades que viven completamente fuera de las distribuciones de Linux y, por lo tanto, no son detectadas por los escáneres de seguridad. Es lo suficientemente difícil para los consumidores de software darse cuenta cuando están ejecutando paquetes de software malicioso, y mucho más complicado poder ser lo suficientemente ágiles como para parchearlos rápidamente con actualizaciones cuando presenten este problema.
El futuro de los proyectos open source
En 2024, veremos cómo se cierran las brechas de seguridad en la cadena de suministro de software entre CVE, distribuciones de Linux y paquetes de software. Veremos una reducción importante en los artefactos de software no esenciales que se incluyen dentro de las distribuciones e imágenes, y las distribuciones mismas comenzarán a competir en función de su propia eficiencia. Un factor determinante en esta carrera será la velocidad que puedan conseguir a la hora de enviar correcciones de vulnerabilidad, en esto cabe destacar claramente Wolfi.
Comenzaremos a escuchar a los equipos de seguridad alinear sus expectativas de seguridad en la infraestructura de aplicaciones con conceptos de confianza cero, y ya no aceptarán tanto caos y desesorden en sus distribuciones e imágenes (todo esto puede introducir grietas y puertas traseras a dependencias transitivas). Veremos equipos de seguridad que quieren acercarse al kernel con tecnologías como eBPF y Cilium, y utilizar la aplicación de políticas de seguridad en tiempo de ejecución con proyectos como Tetragon.
Inteligencia artificial y siguientes pasos
También podremos ver que este bloqueo se va a acelerar con toda la carrera de IA que estamos viviendo a día de hoy. Todos los casos de uso de inteligencia artificial que están pidiendo a las empresas supone un paso más en el proceso que confianza con respecto a marco de dependencias externas que tienen arquitecturas especializadas de GPU y puertas traseras cada vez más sutiles.
Para que los desarrolladores puedan continuar disfrutando de la libertad de elección a la hora de trabajar y elegir recursos open source sin tener mayor problemática en el proceso, es importante que la distribución de software pase por una reevaluación.
Además: ¿ Tienes 10 horas? Aprende IA gratis con IBM
Se necesitan implementar procesos que estandarizen y unifiquen la forma de construir, empaquetar, firmar y verificar todo el código fuente que se incluye en paquetes y contenedores. Para ello, la distribución de estos componentes nativos cloud deben mantener una arquitectura minimalista y guardarse en entornos seguros.
Todos estos recursos son ahora mismo los que más se utilizan y están en boca de toda la comunidad IT, por lo que tienen el lugar perfecto para ser refactorizarizados y con eso ir arraigando las raíces de confianza que apoyarán solidez a las próximas décadas de innovación de código abierto en el mundo.