Prácticas recomendadas para una cadena de suministro de software seguro
El código abierto es omnipresente. Está en muchos códigos base propietarios y en proyectos de la comunidad. En el caso de organizaciones e individuos, la pregunta actual no es tanto si se usa el código abierto, sino qué código abierto se usa y en qué medida.
Si desconoce lo que hay en la cadena de suministro de software, una vulnerabilidad de nivel superior en una de las dependencias puede ser grave, lo que hace que usted y los clientes sean vulnerables a posibles riesgos. En este documento, se profundizará en el término "cadena de suministro de software", su importancia y cómo puede ayudar a proteger la cadena de suministro del proyecto mediante procedimientos recomendados.
Dependencias
El término "cadena de suministro de software" se usa para hacer referencia a todo lo que entra en el software y su procedencia. La cadena de suministro de software depende de las dependencias y de sus propiedades. Una dependencia es lo que debe ejecutar el software. Puede ser código, archivos binarios u otros componentes, y su procedencia, como un repositorio o un administrador de paquetes.
Incluye quién ha escrito el código, cuándo se ha contribuido, cómo se ha revisado en busca de problemas de seguridad, las vulnerabilidades conocidas, las versiones admitidas, la información de licencia y todo lo que la toca en cualquier momento del proceso.
La cadena de suministro también abarca otros elementos de la pila más allá de una sola aplicación, como los scripts de compilación y empaquetado, o bien el software que ejecuta la infraestructura en la que se basa la aplicación.
Vulnerabilidades
En la actualidad, las dependencias de software son generalizadas. Es muy habitual que en los proyectos se usen cientos de dependencias de código abierto para la funcionalidad que no se ha tenido que escribir personalmente. Esto puede significar que la mayor parte de la aplicación se compone de código que no ha creado.
Las posibles vulnerabilidades en las dependencias de terceros o de código abierto son, supuestamente, las que no puede controlar de forma tan estricta como en el código que escribe, lo que puede crear posibles riesgos de seguridad en la cadena de suministro.
Si una de estas dependencias tiene una vulnerabilidad, lo más probable es que usted también tenga una vulnerabilidad. Esto puede resultar terrible, ya que una de las dependencias puede cambiar sin que lo sepa. Incluso si actualmente existe una vulnerabilidad en una dependencia, pero no se usa de forma malintencionada, en el futuro se usará.
Poder aprovechar el trabajo de miles de desarrolladores de código abierto y creadores de bibliotecas significa que miles de extraños pueden colaborar de forma eficaz directamente en el código de producción. El producto, a través de la cadena de suministro de software, se ve afectado por vulnerabilidades sin revisar, errores inocentes o incluso ataques malintencionados contra las dependencias.
Ataques a la cadena de suministro
La definición tradicional de una cadena de suministro procede de la fabricación; es la cadena de procesos necesarios para crear algo y suministrarlo. Incluye los procesos de planificación, suministro de materiales, fabricación y venta al por menor. Una cadena de suministro de software es similar, pero consta de código, y no de materiales. En lugar de fabricación, se trata de desarrollo. En lugar de profundizar desde el principio, el código se obtiene de proveedores (comerciales o de código abierto) y, en general, el código abierto proviene de repositorios. Agregar código desde un repositorio significa que el producto toma una dependencia de ese código.
Un ejemplo de ataque de cadena de suministro de software se da cuando se agrega intencionadamente código malintencionado a una dependencia y se usa la cadena de suministro de dicha dependencia para distribuir el código entre las víctimas. Los ataques de la cadena de suministro son reales. Hay muchos métodos para atacar una cadena de suministro: insertar directamente código malintencionado como colaborador nuevo, apropiarse de la cuenta de un colaborador sin que otros usuarios lo noten o poner en peligro una clave de firma para distribuir software que oficialmente no forma parte de la dependencia.
Un ataque de la cadena de suministro de software no suele ser el objetivo final, sino que es el principio de una oportunidad para que un atacante inserte malware o proporcione una puerta trasera para el acceso futuro.
Software sin revisar
Hoy en día, el uso de código abierto es significativo y no se espera que se ralentice a corto plazo. Como el software de código abierto no se va a dejar de usar, la amenaza para la seguridad de la cadena de suministro es el software sin revisar. Por tanto, ¿cómo puede resolver el riesgo de que una dependencia del proyecto tenga una vulnerabilidad?
- Conviene saber lo que hay en el entorno. Para esto es necesario detectar las dependencias y las dependencias transitivas a fin de comprender sus riesgos, como los de las vulnerabilidades o las restricciones de licencia.
- Administre las dependencias. Cuando se detecta una nueva vulnerabilidad de seguridad, debe determinar si le afecta y, en caso afirmativo, realizar la actualización a la versión más reciente y la revisión de seguridad disponibles. Esto es especialmente importante para revisar los cambios que presentan nuevas dependencias o para auditar de forma periódica las más antiguas.
- Supervise la cadena de suministro. Esto se realiza mediante la auditoría de los controles que se han implementado para administrar las dependencias. Le ayudará a aplicar condiciones más restrictivas que las dependencias deben cumplir.
Trataremos las diversas herramientas y técnicas que NuGet y GitHub proporcionan, y que puede usar hoy para abordar los posibles riesgos en el proyecto.
Conocimiento de lo que hay en el entorno
Paquetes con vulnerabilidades conocidas
📦 Consumidor de paquetes | 📦🖊 Creador de paquetes
.NET 8 y Visual Studio 17.8 agregaron NuGetAudit, que advertirá sobre paquetes directos con vulnerabilidades conocidas durante la restauración. .NET 9 y Visual Studio 17.12 cambiaron también el valor predeterminado para advertir sobre los paquetes transitivos.
NuGetAudit requiere un origen para proporcionar una base de datos de vulnerabilidades conocidas, por lo que si no usa nuget.org como origen de paquetes, debe agregarlo como origen de auditoría.
Cuando NuGet le advierte, la vulnerabilidad se conoce públicamente. Los atacantes pueden usar esta divulgación pública para desarrollar ataques para destinos que no han revisado sus aplicaciones. Por lo tanto, cuando reciba una advertencia de que un paquete que usa el proyecto tiene una vulnerabilidad conocida, debe tomar medidas rápidamente.
Gráfico de dependencias de NuGet
📦 Consumidor de paquetes
Puede ver las dependencias de NuGet en el proyecto si examina directamente el archivo del proyecto correspondiente.
Se suele encontrar en uno de los dos lugares siguientes:
packages.config
: en la raíz del proyecto.<PackageReference>
: en el archivo del proyecto.
En función del método que use para administrar las dependencias de NuGet, también puede utilizar Visual Studio para verlas directamente en el Explorador de soluciones o en el Administrador de paquetes NuGet.
En los entornos de CLI, puede usar el comando dotnet list package
para enumerar las dependencias del proyecto o de la solución.
También puede usar el comando dotnet nuget why
para comprender por qué se incluyen paquetes transitivos (los que no hacen referencia directamente al proyecto) en el gráfico de paquetes del proyecto.
Para obtener más información sobre la administración de dependencias de NuGet, vea la documentación siguiente.
Gráfico de dependencias de GitHub
📦 Consumidor de paquetes | 📦🖊 Creador de paquetes
Puede usar el gráfico de dependencias de GitHub para ver los paquetes de los que depende el proyecto, así como los repositorios que dependen de él. Esto puede ayudarle a ver las vulnerabilidades detectadas en sus dependencias.
Para obtener más información sobre las dependencias del repositorio de GitHub, vea la documentación siguiente.
Versiones de las dependencias
📦 Consumidor de paquetes | 📦🖊 Creador de paquetes
Para garantizar una cadena de dependencias segura, querrá asegurarse de que todas las dependencias y las herramientas se actualizan de forma periódica a la versión estable más reciente, ya que a menudo incluirán la funcionalidad y las revisiones de seguridad más recientes para las vulnerabilidades conocidas. Las dependencias pueden incluir código del que dependa, archivos binarios que utilice, herramientas que use y otros componentes. Esto puede incluir:
Administración de las dependencias
Dependencias de NuGet en desuso y vulnerables
📦 Consumidor de paquetes | 📦🖊 Creador de paquetes
Puede usar la CLI de dotnet para obtener una lista de las dependencias conocidas vulnerables o en desuso que puede incluir el proyecto o la solución.
Puede usar los comandos dotnet list package --deprecated
o dotnet list package --vulnerable
para proporcionar una lista de las vulnerabilidades o los elementos en desuso conocidos.
NuGetAudit puede advertirle sobre las dependencias vulnerables conocidas y está habilitada de forma predeterminada cuando un origen proporciona una base de datos de vulnerabilidades.
Dependencias vulnerables de GitHub
📦 Consumidor de paquetes | 📦🖊 Creador de paquetes
Si el proyecto se hospeda en GitHub, puede aprovechar la seguridad de GitHub para encontrar vulnerabilidades de seguridad y errores en el proyecto, y Dependabot los corregirá mediante la apertura de una solicitud de incorporación de cambios en el código base.
La detección de dependencias vulnerables antes de que se introduzcan es un objetivo del movimiento de "desplazamiento a la izquierda". Para ayudarle a hacerlo es recomendable poder tener información sobre las dependencias, como sus licencias, las dependencias transitivas y la antigüedad de las dependencias.
Para obtener más información sobre las alertas de Dependabot y las actualizaciones de seguridad, vea la documentación siguiente.
Fuentes de NuGet
📦 Consumidor de paquetes
Utilice orígenes de paquetes fiables. Cuando se usan varias fuentes de origen de NuGet públicas y privadas, se puede descargar un paquete desde cualquiera de ellas. Para asegurarse de que la compilación es predecible y segura contra ataques conocidos, como la confusión de dependencias, un procedimiento recomendado consiste en conocer de qué fuentes concretas proceden los paquetes. Puede usar una fuente única o una fuente privada con funciones ascendentes para la protección.
Para obtener más información sobre cómo proteger las fuentes de paquetes, vea 3 formas de mitigar los riesgos al usar fuentes de paquetes privadas.
Al usar un feed privado, consulte los procedimientos recomendados de seguridad para administrar las credenciales.
Directivas de confianza de cliente
📦 Consumidor de paquetes
Hay directivas que se pueden activar en las que se exige que los paquetes que usa estén firmados. Esto le permite confiar en el creador de un paquete, siempre y cuando esté firmado por el creador, o bien confiar en un paquete si es propiedad de un usuario o una cuenta específicos que está firmado por NuGet.org.
Para configurar directivas de confianza de cliente, vea la documentación siguiente.
Archivos de bloqueo
📦 Consumidor de paquetes
Los archivos de bloqueo almacenan el hash del contenido del paquete. Si el hash de contenido de un paquete que quiere instalar coincide con el archivo de bloqueo, garantizará la repetibilidad del paquete.
Para habilitar los archivos de bloqueo, vea la documentación siguiente.
Asignación de origen del paquete
📦 Consumidor de paquetes
La asignación de origen del paquete le permite declarar de forma centralizada desde qué origen debe restaurar cada paquete de su solución en su archivo nuget.config.
Para habilitar la asignación de origen del paquete, consulte la documentación siguiente.
Ordenadores seguros
Permisos del directorio
📦 Consumidor de paquetes
En Windows y Mac, y algunas distribuciones de Linux, los directorios principales de la cuenta de usuario son privados de manera predeterminada. Sin embargo, algunas distribuciones de Linux hacen que otros directorios de usuario sean legibles por otras cuentas del mismo equipo de manera predeterminada. Además, hay varias opciones de configuración para redirigir la carpeta de paquetes globales de NuGet y la caché HTTP a ubicaciones no predeterminadas. Las soluciones, los proyectos y los repositorios también se pueden crear fuera del directorio principal del usuario.
Si utiliza algún paquete que no esté en nuget.org, entonces si cualquier otra cuenta en el ordenador puede leer los paquetes globales de NuGet o los directorios de caché HTTP, o el directorio de salida de construcción del proyecto, entonces estos paquetes podrían ser revelados a personas que no deberían tener acceso a esos paquetes.
En Linux, dotnet nuget update source
cambiará los permisos de archivo nuget.config para que solo sea legible por el propietario del archivo.
Sin embargo, si edita el archivo nuget.config de cualquier otra manera y el archivo se encuentra en una ubicación en la que otras cuentas pueden leer el archivo, puede haber divulgación de información sobre la dirección URL del origen del paquete o las credenciales de origen del paquete.
Debe asegurarse de que otros usuarios del mismo equipo no puedan leer ningún archivo nuget.config.
Soluciones dentro del directorio de descargas
📦 Consumidor de paquetes
Se debe tener cuidado adicional si se trabaja en soluciones o proyectos en el directorio de descargas. NuGet acumulará la configuración de varios archivos de configuración y MSBuild importará Directory.Build.props, Directory.NuGet.props, Directory.Build.targets y potencialmente otros archivos desde cualquier directorio primario hasta la raíz del sistema de archivos.
La carpeta de descargas tiene un riesgo adicional, ya que normalmente es la ubicación predeterminada que los navegadores web descargarán archivos de Internet.
Agentes de compilación
📦 Consumidor de paquetes
Los agentes de compilación (agentes de CI) que no se restablecen a un estado inicial después de que cada compilación tenga varios riesgos que se deben tener en cuenta.
Para obtener información sobre las formas seguras de administrar las credenciales, consulte la documentación sobre el consumo de paquetes de fuentes autenticadas.
Para obtener información sobre cómo modificar los directorios en los que NuGet almacena datos, consulte los documentos sobre cómo administrar los paquetes globales, la memoria caché y las carpetas temporales. Estos directorios deben configurarse en un directorio que el agente de CI limpia después de cada compilación.
Tenga en cuenta que los paquetes usados por el proyecto podrían dejarse en el directorio de salida de compilación del proyecto. Si el proyecto usa paquetes de orígenes autenticados, es posible que otros usuarios del mismo agente de CI obtengan acceso no autorizado a los ensamblados del paquete. Por lo tanto, también debe limpiar el repositorio al final de la compilación, incluso cuando se produce un error en la compilación o se cancela.
Supervisión de la cadena de suministro
Escaneo de secretos de GitHub
📦🖊 Creador de paquetes
GitHub examina los repositorios en busca de claves de API de NuGet para evitar usos fraudulentos de secretos que se hayan confirmado accidentalmente.
Para obtener más información sobre el examen de secretos, vea Información sobre el examen de secretos.
Firma del creador del paquete
📦🖊 Creador de paquetes
La firma del creador permite que el creador del paquete plasme su identidad en un paquete y que un consumidor compruebe que procede de usted. Esto le protege contra la alteración del contenido, y sirve como un origen único de verdad sobre el origen y la autenticidad del paquete. Cuando se combina con directivas de confianza de cliente, puede comprobar que un paquete proviene de un creador específico.
Para crear una firma de un paquete, vea Firma de un paquete.
Compilaciones reproducibles
📦🖊 Creador de paquetes
Las compilaciones reproducibles crean archivos binarios que son idénticos byte a byte cada vez que se compilan, y contienen vínculos de código fuente y metadatos del compilador que permiten a un consumidor de paquetes volver a crear el binario directamente y validar que el entorno de compilación no se haya puesto en peligro.
Para obtener más información sobre las compilaciones reproducibles, consulte Producing Packages with Source Link (Generación de paquetes con vínculo de origen) y la especificación Reproducible Build Validation (Validación de compilación reproducible).
Autenticación en dos fases (2FA)
📦🖊 Creador de paquetes
Cada cuenta de nuget.org tiene habilitada la 2FA. Esto agrega una capa adicional de seguridad al iniciar sesión en la cuenta de GitHub o en la cuenta de NuGet.org.
Reserva de prefijo de identificador de paquete
📦🖊 Creador de paquetes
Para proteger la identidad de los paquetes, puede reservar un prefijo de identificador de paquete con el espacio de nombres correspondiente para asociar un propietario coincidente si el prefijo del identificador del paquete coincide con los criterios especificados.
Para obtener información sobre cómo reservar prefijos de identificador, vea Reserva de prefijos de identificador de paquete.
Desuso y descarte de un paquete vulnerable
📦🖊 Creador de paquetes
Para proteger el ecosistema de paquetes de .NET cuando identifique una vulnerabilidad en un paquete que ha creado, debe esforzarse por dejar el paquete en desuso y quitarlo de la lista, de modo que esté oculto para los usuarios que buscan paquetes. Evite usar un paquete que esté en desuso y que no aparezca en la lista.
Para obtener información sobre cómo dejar de usar un paquete y quitarlo de la lista, vea la documentación siguiente sobre cómo dejar de usar paquetes y quitarlos de la lista.
Considere también la posibilidad de notificar lo conocido a la base de datos de avisos de GitHub.
Resumen
La cadena de suministro de software es todo lo que entra o afecta al código. Aunque los peligros de la cadena de suministro son reales y cada vez más conocidos, siguen siendo poco frecuentes, por lo que lo más importante que puede hacer es proteger la cadena de suministro, para lo que debe conocer las dependencias, administrarlas y supervisar la cadena de suministro.
Ha obtenido información sobre los distintos métodos que se proporcionan en NuGet y GitHub, y que están disponibles hoy en día para mejorar la eficacia a la hora de examinar, administrar y supervisar la cadena de suministro.
Para obtener más información sobre cómo proteger el software del mundo, vea el informe de seguridad The State of the Octoverse 2020.