Introducción

En este artículo uso Grype, de Anchore, para encontrar vulnerabilidades conocidas (CVE) en las dependencias NuGet y en la imagen Docker de una API .NET 8, todo automatizado con GitHub Actions.

La mayor parte del código de una aplicación moderna no lo escribimos nosotros: viene de librerías y de la imagen base del contenedor. El análisis de composición de software (SCA) revisa esas piezas contra bases de datos de vulnerabilidades públicas.

Elegí Grype porque está en la lista de herramientas de escaneo de vulnerabilidades de OWASP, es gratuito y de código abierto, escanea tanto carpetas como imágenes Docker, y exporta resultados en SARIF para GitHub. Este trabajo complementa el de mi compañero Victor Carretero, que analiza el código fuente con DevSkim en el mismo pipeline.

La aplicación y el repositorio público

La aplicación es Banco API, una Minimal API en .NET 8 empaquetada en Docker. A propósito usa Newtonsoft.Json 12.0.1, una versión afectada por CVE-2024-21907 (denegación de servicio con JSON profundamente anidado), para que Grype tenga qué detectar.

Repositorio público del equipo: github.com/viccarretero/banco-api-vulnerabilidades

La dependencia vulnerable en BancoApi.csproj:

<PackageReference Include="Newtonsoft.Json" Version="12.0.1" /> 

El Dockerfile compila en dos etapas, así la imagen final solo lleva el runtime de ASP.NET y la app publicada:

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /src COPY src/BancoApi/ ./ RUN dotnet publish -c Release -o /app FROM mcr.microsoft.com/dotnet/aspnet:8.0 WORKDIR /app COPY --from=build /app . ENTRYPOINT ["dotnet", "BancoApi.dll"] 

Grype escanea esa imagen completa: los paquetes del sistema operativo de la imagen base y las librerías .NET que aparecen en el archivo BancoApi.deps.json.

Automatización con GitHub Actions

En cada push o pull request a main, el workflow .github/workflows/seguridad.yml construye la imagen y la escanea con Grype, sin pasos manuales:

  1. build: compila la API con .NET 8.
  2. grype: construye la imagen Docker, la escanea con la acción oficial anchore/scan-action y sube el SARIF a GitHub Code Scanning.
  3. publicar: junta el reporte de Grype con el de DevSkim y los despliega en GitHub Pages.

El job de Grype:

- name: Construir imagen Docker run: docker build -t banco-api:${{ github.sha }} . - name: Ejecutar Grype id: scan uses: anchore/scan-action@v6 with: image: banco-api:${{ github.sha }} fail-build: false output-format: sarif - name: Publicar hallazgos en GitHub Code Scanning uses: github/codeql-action/upload-sarif@v3 with: sarif_file: ${{ steps.scan.outputs.sarif }} category: grype 

Con fail-build: false el pipeline reporta sin bloquear el despliegue; en un proyecto real se cambia a true con severity-cutoff: high para frenar los cambios que introduzcan vulnerabilidades graves. En local basta con:

docker build -t banco-api . grype banco-api 

Resultados y publicación en la nube

Los hallazgos de Grype quedan en la pestaña Security → Code scanning del repositorio y en un reporte HTML público en GitHub Pages.

Reporte publicado: viccarretero.github.io/banco-api-vulnerabilidades/grype

En la primera ejecución, Grype encontró 226 vulnerabilidades en la imagen: 52 de severidad alta o crítica, 80 media y 94 baja. Casi todas vienen de la imagen base, no del código del equipo.

Origen Ejemplo Severidad Riesgo
Paquete NuGet (BancoApi.deps.json) Newtonsoft.Json 12.0.1 — GHSA-5crp-9r3c-p9vr / CVE-2024-21907 Alta Un JSON muy anidado puede tumbar el servicio
Imagen base Debian (aspnet:8.0) libtasn1-6 — CVE-2025-13151 Alta Falla en una librería del sistema que la app no controla
Imagen base Debian (aspnet:8.0) libgnutls30 — CVE-2011-3389 Baja CVE antiguo sin corrección disponible en la distribución

Cada hallazgo indica el paquete, la versión instalada, la versión que lo corrige y el enlace al CVE.

Cómo corregir las vulnerabilidades

La corrección en SCA casi siempre es actualizar: subir la librería a la versión parcheada y reconstruir la imagen.

<!-- Newtonsoft.Json 13.0.1 o superior corrige CVE-2024-21907 --> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> 
# Imagen base más pequeña = menos paquetes y menos CVE FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine 

Tras el push, el pipeline vuelve a construir y escanear, y el reporte en Pages muestra menos hallazgos. Si un CVE no aplica al proyecto, se puede ignorar de forma documentada en un archivo .grype.yaml.

Conclusiones

Grype cubre lo que el análisis de código no ve: las vulnerabilidades heredadas de librerías y de la imagen base. Junto con DevSkim (SAST), el equipo revisa en cada cambio tanto el código propio como el de terceros, y publica los resultados sin intervención manual.

Enlaces

Gerald Deybi Zevallos Pinto — Calidad y Pruebas de Software, Universidad Privada de Tacna.