Escaneo de vulnerabilidades en .NET con DevSkim y GitHub Actions
Introducción En este artículo integro DevSkim, un analizador estático de seguridad (SAST) de Microsoft, en un pipeline de GitHub Actions que escanea una API .NET 8 en cada cambio y publica el reporte en la nube. El es
Introducción
En este artículo integro DevSkim, un analizador estático de seguridad (SAST) de Microsoft, en un pipeline de GitHub Actions que escanea una API .NET 8 en cada cambio y publica el reporte en la nube.
El escaneo de vulnerabilidades busca fallas de seguridad conocidas antes de que el código llegue a producción. Las herramientas SAST revisan el código fuente sin ejecutarlo y señalan patrones riesgosos: algoritmos criptográficos débiles, credenciales escritas en el código o conexiones sin cifrar.
Elegí DevSkim porque figura en la lista de herramientas de escaneo de vulnerabilidades de OWASP, es gratuito y de código abierto, soporta C# y otros lenguajes, y genera resultados en formato SARIF, el estándar que GitHub entiende de forma nativa.
La aplicación y el repositorio público
La aplicación de ejemplo es Banco API, una Minimal API en .NET 8 con endpoints para consultar saldos, generar hashes y tokens. Incluí vulnerabilidades intencionales para que DevSkim tenga qué encontrar.
Repositorio público del equipo: github.com/viccarretero/banco-api-vulnerabilidades. El mismo pipeline también corre Grype, que analiza las dependencias y la imagen Docker; eso lo explica mi compañero Gerald Zevallos en su artículo.
| Archivo | Para qué sirve |
|---|---|
src/BancoApi/Program.cs |
API con las vulnerabilidades de ejemplo |
.github/workflows/seguridad.yml |
Pipeline de CI que compila, escanea y publica |
scripts/sarif_to_html.py |
Convierte el SARIF en un reporte HTML |
Un fragmento del código vulnerable:
// Credenciales en el código
const string ConnectionString = "Server=db.banco.local;User Id=admin;Password=Admin123!;";
// Hash débil (MD5)
using var md5 = MD5.Create();
// Aleatorio no criptográfico para tokens
var random = new Random();
// Comunicación sin cifrar
Results.Redirect("http://api.tipocambio.example.com/usd");
Automatización con GitHub Actions
El escaneo corre solo en cada push o pull request a main, sin que nadie lo ejecute a mano. El workflow tiene cuatro jobs:
- build: instala .NET 8 y compila la API.
-
devskim: ejecuta la acción oficial
microsoft/DevSkim-Action, sube el SARIF a GitHub Code Scanning y genera el reporte HTML. - grype: escanea la imagen Docker (ver el artículo de Gerald).
- publicar: despliega los reportes en GitHub Pages.
La parte central del archivo .github/workflows/seguridad.yml:
- name: Ejecutar DevSkim
uses: microsoft/DevSkim-Action@v1
with:
directory-to-scan: src
output-filename: devskim-results.sarif
- name: Publicar hallazgos en GitHub Code Scanning
uses: github/codeql-action/upload-sarif@v3
with:
sarif\\\_file: devskim-results.sarif
category: devskim
- name: Generar reporte HTML
run: |
mkdir -p site/devskim
python3 scripts/sarif\\\_to\\\_html.py devskim-results.sarif site/devskim/index.html DevSkim
Para que funcione, el workflow pide los permisos security-events: write (subir hallazgos) y pages: write + id-token: write (publicar en Pages). También se puede correr en local:
dotnet tool install --global Microsoft.CST.DevSkim.CLI
devskim analyze --source-code src --output-file devskim-results.sarif
Resultados y publicación en la nube
Cada ejecución deja los hallazgos en dos lugares: la pestaña Security → Code scanning del repositorio y un reporte HTML público en GitHub Pages.
Reporte publicado: viccarretero.github.io/banco-api-vulnerabilidades/devskim
En la primera ejecución (2 min 8 s en total), DevSkim reportó 10 hallazgos: 8 críticos, 1 importante y 1 moderado.
| Regla | Hallazgo | Severidad | Cantidad |
|---|---|---|---|
| DS126858 | Algoritmo de hash débil (MD5 y SHA1) | Crítico | 8 |
| DS137138 | URL insegura (http://) |
Importante | 1 |
| DS176209 | Comentario sospechoso (TODO) |
Moderado | 1 |
DevSkim no detectó la contraseña escrita en la cadena de conexión ni el uso de System.Random para tokens. Es una limitación real del SAST basado en patrones: conviene complementarlo con un detector de secretos y revisión de código.
Cómo corregir los hallazgos
Cada hallazgo tiene una corrección corta en .NET; al aplicarlas y hacer push, el pipeline vuelve a escanear y el reporte se actualiza solo.
// Credenciales: leerlas de configuración o variables de entorno
var connectionString = builder.Configuration.GetConnectionString("Banco");
// Hash: usar SHA-256 (o PBKDF2/Argon2 para contraseñas)
var hash = SHA256.HashData(Encoding.UTF8.GetBytes(texto));
// Tokens: generador criptográficamente seguro
var token = RandomNumberGenerator.GetInt32(100000, 999999);
// Comunicaciones: siempre HTTPS
Results.Redirect("https://api.tipocambio.example.com/usd");
Si un hallazgo es un falso positivo, DevSkim permite suprimirlo con un comentario en la línea (// DevSkim: ignore DS126858), dejando constancia de la decisión.
Conclusiones
Con un solo archivo de workflow, DevSkim convierte el escaneo de seguridad en un paso automático del desarrollo: cada cambio se revisa y el equipo ve los riesgos antes de desplegar. Al ser SAST, no reemplaza a las pruebas dinámicas (DAST) ni al análisis de dependencias; lo ideal es combinarlo con ellas.
Enlaces
- Repositorio: github.com/viccarretero/banco-api-vulnerabilidades
- Reportes en GitHub Pages: viccarretero.github.io/banco-api-vulnerabilidades
- Ejecución del pipeline: GitHub Actions
- Video: (pendiente)
- Artículo complementario sobre Grype (Gerald Zevallos): (pendiente)
- DevSkim en GitHub
- Herramientas de escaneo de vulnerabilidades — OWASP
Victor Carretero — Calidad y Pruebas de Software, Universidad Privada de Tacna.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.