Seguridad en el pipeline de CI/CD
Su pipeline de CI/CD es la última línea de defensa antes de que el código llegue a producción. Cada commit, cada pull request, cada despliegue pasa por él. Eso lo convierte en el lugar ideal para detectar problemas de seguridad: vulnerabilidades en su código, dependencias peligrosas, configuraciones incorrectas, secretos filtrados.
El objetivo no es bloquear cada build con advertencias de seguridad. Es detectar los problemas críticos de forma automática, dar retroalimentación rápida a los desarrolladores y evitar que los problemas evidentes lleguen a producción. Un pipeline bien configurado detecta inyecciones SQL antes de la revisión de código, señala dependencias vulnerables antes del merge y bloquea patrones conocidos como peligrosos antes de que lleguen a producción.
Este capítulo cubre los cinco tipos de análisis de seguridad que necesita en CI/CD: análisis estático (SAST), análisis de dependencias (SCA), lista de materiales de software (SBOM), análisis de infraestructura como código (IaC) y pruebas dinámicas (DAST). Todo usando herramientas gratuitas compatibles con GitHub y GitLab.
Por qué esto importa para las empresas pequeñas
El análisis de seguridad parece una carga propia de grandes empresas. No lo es. Para equipos pequeños, el análisis automatizado es aún más valioso: no tiene revisores de seguridad dedicados, así que el pipeline tiene que hacer ese trabajo.
No puede revisar todo manualmente. Un equipo de cinco desarrolladores puede producir decenas de commits al día. Nadie tiene tiempo de revisar cada cambio desde el punto de vista de seguridad. Los escáneres automatizados detectan los problemas evidentes para que los humanos puedan concentrarse en la arquitectura y la lógica.
Las vulnerabilidades se propagan más rápido en equipos pequeños. No hay comités de cambios, ni aprobaciones en múltiples etapas, ni esperas. El código va del portátil a producción en horas. Esa velocidad es una ventaja, pero también significa que las vulnerabilidades se mueven rápido. El análisis en CI/CD es su red de seguridad.
El riesgo de las dependencias es real. Su aplicación puede tener 10.000 líneas de código que usted escribió y 500.000 líneas de dependencias de código abierto que no. Un paquete vulnerable en esa pila puede comprometer todo. El informe de Snyk 2024 encontró que el 80% de las aplicaciones contienen al menos una vulnerabilidad conocida en sus dependencias.
Las herramientas gratuitas están listas para producción. Semgrep, Trivy, Dependabot, npm audit — estos no son proyectos de juguete. Los usan miles de empresas y detectan vulnerabilidades reales. No necesita una plataforma de seguridad de 50.000 dólares para analizar su código.
Lo que buscan los atacantes
Cuando los atacantes apuntan a una aplicación, suelen comenzar por lo más fácil:
- CVEs conocidos en dependencias — existen exploits públicos, solo hay que encontrar un objetivo que use la versión vulnerable
- Secretos expuestos — claves de API, contraseñas de bases de datos, credenciales cloud en el código o en los registros de CI
- Vulnerabilidades de inyección — inyección SQL, inyección de comandos, XSS que las herramientas automatizadas detectan de forma fiable
- Infraestructura mal configurada — buckets de S3 abiertos, CORS permisivo, cabeceras de seguridad faltantes
El análisis automatizado detecta la mayoría de estos problemas. Los atacantes usan herramientas automatizadas para encontrarlos — usted debe usar herramientas automatizadas para encontrarlos primero.
Tipos de análisis de seguridad
Cinco categorías cubren la mayoría de lo que necesita:
| Tipo | Qué hace | Cuándo se ejecuta | Ejemplos |
|---|---|---|---|
| SAST (Static Application Security Testing) | Analiza el código fuente en busca de vulnerabilidades | Cada commit, PR | Semgrep, CodeQL, Bandit |
| SCA (Software Composition Analysis) | Detecta dependencias vulnerables | Cada build | Dependabot, Snyk, Trivy |
| SBOM (Software Bill of Materials) | Inventaría todos los componentes, rastrea licencias | Cada lanzamiento | Syft, Grype, Dependency-Track |
| Análisis IaC | Detecta configuraciones incorrectas en código de infraestructura | Cada commit | Checkov, tfsec, KICS |
| DAST (Dynamic Application Security Testing) | Prueba la aplicación en ejecución en busca de vulnerabilidades | Despliegues en staging | OWASP ZAP, Nuclei |
Cada tipo detecta problemas diferentes:
- SAST detecta problemas en el código que usted escribe: inyección SQL, XSS, criptografía insegura
- SCA detecta problemas en el código que importa: bibliotecas vulnerables, paquetes desactualizados
- SBOM rastrea qué hay en su software: inventario de componentes, cumplimiento de licencias, correlación de vulnerabilidades
- IaC detecta problemas en la infraestructura: buckets de S3 abiertos, IAM excesivamente permisivo, almacenamiento sin cifrar
- DAST detecta problemas en cómo se ejecuta todo: servidores mal configurados, endpoints expuestos, omisiones de autenticación
Necesita los cinco. Son complementarios, no alternativos.
SAST: análisis estático de código
Las herramientas SAST leen su código fuente y buscan patrones que indiquen vulnerabilidades. Sin tiempo de ejecución, sin despliegue — solo análisis de código.
Qué detecta SAST
| Vulnerabilidad | Cómo la detecta SAST |
|---|---|
| Inyección SQL | Concatenación de cadenas en consultas SQL |
| XSS | Salida sin sanitizar en plantillas HTML |
| Inyección de comandos | Entrada del usuario en comandos de shell |
| Path traversal | Entrada del usuario en operaciones de archivo |
| Secretos en el código | Patrones que coinciden con claves de API, contraseñas |
| Criptografía insegura | Uso de MD5, SHA1 para contraseñas, aleatoriedad débil |
Herramienta: Semgrep
Semgrep es la herramienta SAST de referencia para equipos pequeños. Es rápida, tiene buenas reglas por defecto y se integra con todo.
Instalación local:
# macOS
brew install semgrep
# pip
pip install semgrep
Ejecutar un análisis:
# Analizar con reglas por defecto
semgrep --config auto .
# Analizar con reglas OWASP Top 10
semgrep --config "p/owasp-top-ten" .
# Analizar un lenguaje específico
semgrep --config "p/python" .
Integración con GitHub Actions:
name: Security Scan
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
semgrep:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Semgrep
uses: semgrep/semgrep-action@v1
with:
config: >-
p/security-audit
p/secrets
Integración con GitLab CI:
semgrep:
stage: test
image: semgrep/semgrep
script:
- semgrep ci --config auto
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
Herramienta: CodeQL (solo GitHub)
CodeQL de GitHub es potente pero solo funciona en GitHub. Es gratuito para repositorios públicos e incluido en GitHub Advanced Security para repositorios privados.
Habilitarlo en la configuración del repositorio:
- Vaya a Settings → Security → Code security and analysis
- Active «Code scanning»
- Elija «CodeQL analysis»
- Seleccione los lenguajes a analizar
O configúrelo manualmente:
name: CodeQL
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 6 * * 1' # Weekly Monday 6 AM
jobs:
analyze:
runs-on: ubuntu-latest
permissions:
security-events: write
strategy:
matrix:
language: ['javascript', 'python']
steps:
- uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
Herramientas específicas por lenguaje
| Lenguaje | Herramienta | Instalación | Ejecución |
|---|---|---|---|
| Python | Bandit | pip install bandit | bandit -r src/ |
| JavaScript | ESLint + security plugin | npm i eslint-plugin-security | eslint --ext .js src/ |
| Go | gosec | go install github.com/securego/gosec/v2/cmd/gosec@latest | gosec ./... |
| Ruby | Brakeman | gem install brakeman | brakeman |
| PHP | Psalm | composer require --dev vimeo/psalm | ./vendor/bin/psalm |
Gestión de hallazgos SAST
No todo hallazgo es una vulnerabilidad real. Las herramientas SAST tienen falsos positivos. Así se gestionan:
Clasificación por gravedad:
| Gravedad | Acción | Plazo |
|---|---|---|
| Crítico/Alto | Bloquear el merge, corregir de inmediato | El mismo día |
| Medio | Corregir antes del lanzamiento | Este sprint |
| Bajo | Registrar, corregir cuando sea conveniente | Backlog |
Suprimir falsos positivos correctamente:
# Semgrep: ignorar en línea
password = get_from_vault() # nosemgrep: hardcoded-password
# Bandit: ignorar en línea
subprocess.run(cmd, shell=True) # nosec B602
O use un archivo de configuración:
# .semgrep.yml
rules:
- id: my-custom-rule
# ... rule definition
# Ignore specific paths
exclude:
- "tests/*"
- "vendor/*"
- "*.test.js"
No suprima todo. Si está suprimiendo más del 10% de los hallazgos, o su código tiene problemas o está usando el conjunto de reglas incorrecto.
SCA: análisis de dependencias
Sus dependencias son una superficie de ataque. Las herramientas SCA analizan los manifiestos de paquetes (package.json, requirements.txt, go.mod) y señalan los paquetes con vulnerabilidades conocidas.
Qué detecta SCA
- CVEs conocidos — vulnerabilidades publicadas en versiones específicas de paquetes
- Problemas de licencias — dependencias GPL en código propietario, conflictos de licencias
- Paquetes desactualizados — versiones antiguas sin correcciones de seguridad
- Paquetes maliciosos — typosquatting, maintainers comprometidos
Herramienta: Dependabot (GitHub)
Dependabot está integrado en GitHub. Analiza dependencias, abre PRs para actualizar paquetes vulnerables y mantiene todo al día.
Habilitarlo en el repositorio:
- Vaya a Settings → Security → Code security and analysis
- Active «Dependabot alerts»
- Active «Dependabot security updates»
O configúrelo con un archivo:
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"
Agrupar actualizaciones para reducir el ruido de PRs:
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
groups:
development-dependencies:
dependency-type: "development"
production-dependencies:
dependency-type: "production"
update-types:
- "minor"
- "patch"
Herramienta: Snyk
Snyk funciona con GitHub, GitLab, Bitbucket y de forma independiente. El nivel gratuito cubre pruebas ilimitadas para proyectos de código abierto y análisis limitados para repositorios privados.
Instalar CLI:
npm install -g snyk
snyk auth
Analizar localmente:
# Probar el proyecto actual
snyk test
# Probar y mostrar rutas de remediación
snyk test --show-vulnerable-paths=all
# Monitorizar nuevas vulnerabilidades
snyk monitor
Integración con GitHub Actions:
name: Snyk Security
on:
push:
branches: [main]
pull_request:
jobs:
snyk:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Snyk
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=high
Integración con GitLab CI:
snyk:
stage: test
image: snyk/snyk:node
script:
- snyk auth $SNYK_TOKEN
- snyk test --severity-threshold=high
allow_failure: true # Don't block on medium/low
Herramienta: Trivy
Trivy analiza todo: imágenes de contenedor, sistemas de archivos, repositorios git, manifiestos de Kubernetes, Terraform. Es increíblemente versátil.
Instalación:
# macOS
brew install trivy
# Linux
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
Analizar el sistema de archivos (dependencias):
trivy fs --severity HIGH,CRITICAL .
Analizar una imagen de contenedor:
trivy image --severity HIGH,CRITICAL myapp:latest
GitHub Actions para análisis de contenedores:
name: Container Security
on:
push:
branches: [main]
jobs:
trivy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t myapp:${{ github.sha }} .
- name: Run Trivy
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
severity: 'CRITICAL,HIGH'
exit-code: '1'
Auditorías nativas del gestor de paquetes
La mayoría de los gestores de paquetes tienen análisis de vulnerabilidades integrado:
# npm
npm audit
npm audit fix
# yarn
yarn audit
# pip
pip-audit
# composer
composer audit
# bundler
bundle audit
# go
govulncheck ./...
Agregar al pipeline de CI:
# GitHub Actions - npm audit
- name: Security audit
run: npm audit --audit-level=high
Gestión de vulnerabilidades en dependencias
Cuando una vulnerabilidad tiene solución:
- Actualice a la versión corregida
- Ejecute las pruebas
- Despliegue
Cuando no hay solución disponible:
- Compruebe si realmente usa la función vulnerable
- Evalúe el riesgo real — ¿es alcanzable la ruta de código vulnerable?
- Considere paquetes alternativos
- Si el riesgo es aceptable, documéntelo y monitorícelo
Cuando las actualizaciones rompen cosas:
- Compruebe si es un cambio incompatible al que puede adaptarse
- Fije temporalmente la versión actual
- Cree un ticket para corregirlo correctamente
- Establezca un plazo — no lo deje indefinidamente
SBOM: Software Bill of Materials
Un SBOM es un inventario completo de todos los componentes de su software — cada biblioteca, framework y dependencia, con versiones y orígenes. Piénselo como la lista de ingredientes de su aplicación.
Por qué importa el SBOM
Velocidad de respuesta ante incidentes. Cuando Log4Shell ocurrió en diciembre de 2021, las organizaciones con SBOMs supieron en pocas horas qué aplicaciones estaban afectadas. Las que no tenían SBOMs tardaron días o semanas en investigar manualmente. La Orden Ejecutiva de Ciberseguridad de EE.UU. 14028 ahora exige SBOMs para el software vendido al gobierno federal.
Visibilidad de la cadena de suministro. Su aplicación depende del paquete A, que depende de B, que depende de C. Una vulnerabilidad en C le afecta a usted, pero puede que no sepa que C existe sin un SBOM. Las dependencias transitivas son invisibles sin las herramientas adecuadas.
Cumplimiento de licencias. Ese paquete con licencia MIT que usa puede depender de una biblioteca GPL. Sin un SBOM, no lo sabrá hasta que el departamento legal llame a la puerta. El análisis de licencias requiere conocer cada componente de su pila.
Requisitos de clientes. Los clientes empresariales exigen cada vez más SBOMs como parte de las evaluaciones de seguridad de proveedores. Los sectores de salud, finanzas y gobierno suelen exigirlos.
Formatos SBOM
Dos formatos principales dominan:
| Formato | Mantenedor | Mejor para | Enlace |
|---|---|---|---|
| SPDX | Linux Foundation | Cumplimiento de licencias, adopción amplia | spdx.dev |
| CycloneDX | OWASP | Enfoque en seguridad, seguimiento de vulnerabilidades | cyclonedx.org |
Ambos son legibles por máquina (JSON, XML) e intercambiables para la mayoría de propósitos. CycloneDX tiene mejor correlación de vulnerabilidades; SPDX tiene mayor adopción industrial para el cumplimiento de licencias.
Generación de SBOMs
Herramienta: Syft — el estándar para la generación de SBOMs
# Install
brew install syft
# or
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
# Generate SBOM from directory
syft dir:. -o cyclonedx-json > sbom.json
# Generate from container image
syft myapp:latest -o spdx-json > sbom.spdx.json
# Generate from package lock files
syft dir:. -o cyclonedx-json --catalogers javascript
GitHub Actions:
- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
image: myapp:${{ github.sha }}
format: cyclonedx-json
output-file: sbom.json
- name: Upload SBOM
uses: actions/upload-artifact@v4
with:
name: sbom
path: sbom.json
GitLab CI:
generate_sbom:
stage: build
image: anchore/syft
script:
- syft dir:. -o cyclonedx-json > sbom.json
artifacts:
paths:
- sbom.json
Otros generadores de SBOM:
| Herramienta | Tipo | Mejor para | Enlace |
|---|---|---|---|
| Syft | CLI | Generación universal | GitHub |
| Trivy | CLI | Análisis combinado + SBOM | trivy.dev |
| cdxgen | CLI | Nativo CycloneDX | GitHub |
| Microsoft SBOM Tool | CLI | .NET, general | GitHub |
| SPDX SBOM Generator | CLI | Nativo SPDX | GitHub |
Análisis de SBOMs en busca de vulnerabilidades
Una vez que tiene un SBOM, analícelo en busca de vulnerabilidades conocidas:
Herramienta: Grype — escáner de vulnerabilidades que consume SBOMs
# Install
brew install grype
# Scan SBOM for vulnerabilities
grype sbom:sbom.json
# Scan with severity filter
grype sbom:sbom.json --only-fixed --fail-on high
GitHub Actions:
- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
image: myapp:latest
output-file: sbom.json
- name: Scan SBOM for vulnerabilities
uses: anchore/scan-action@v3
with:
sbom: sbom.json
fail-build: true
severity-cutoff: high
Otros escáneres de vulnerabilidades para SBOMs:
| Herramienta | Precio | Características | Enlace |
|---|---|---|---|
| Grype | Gratuito | Rápido, nativo para SBOM | GitHub |
| Trivy | Gratuito | Escáner universal | trivy.dev |
| OSV-Scanner | Gratuito | Base de datos OSV de Google | GitHub |
| Snyk | Nivel gratuito | Mejor asesoramiento de remediación | snyk.io |
| OWASP Dependency-Track | Gratuito (autoalojado) | Plataforma completa de gestión de SBOM | dependencytrack.org |
| Anchore Enterprise | De pago | Motor de políticas, cumplimiento | anchore.com |
| Sonatype Nexus Lifecycle | De pago | Análisis profundo, políticas | sonatype.com |
Análisis de SBOMs para el cumplimiento de licencias
Los problemas de licencias pueden ser tan dañinos como las vulnerabilidades de seguridad: exposición legal, obligación de publicar código propietario como código abierto, o imposibilidad de distribuir a ciertos clientes.
Preocupaciones comunes sobre licencias:
| Tipo de licencia | Preocupación | Licencias de ejemplo |
|---|---|---|
| Copyleft | Puede requerir publicar su código como código abierto | GPL, AGPL, LGPL |
| Copyleft débil | Requiere atribución, algunas restricciones | MPL, EPL |
| Permisiva | Generalmente segura para uso comercial | MIT, Apache 2.0, BSD |
| Desconocida | Sin licencia = todos los derechos reservados | Paquetes sin licencia |
Herramienta: OWASP Dependency-Track — gestión completa de SBOM
Dependency-Track es una plataforma gratuita y autoalojada que ingiere SBOMs y proporciona:
- Seguimiento de vulnerabilidades en todos los proyectos
- Análisis de cumplimiento de licencias
- Aplicación de políticas
- Seguimiento histórico
# Run with Docker
docker run -d -p 8080:8080 dependencytrack/bundled
Luego cargue los SBOMs mediante la API o la interfaz de usuario.
Herramientas comerciales para el cumplimiento de licencias:
| Herramienta | Precio | Características | Enlace |
|---|---|---|---|
| OWASP Dependency-Track | Gratuito (autoalojado) | Plataforma SBOM completa | dependencytrack.org |
| FOSSA | Nivel gratuito, planes de pago | Análisis profundo de licencias | fossa.com |
| Snyk | Nivel gratuito | Análisis de licencias incluido | snyk.io |
| Mend (WhiteSource) | De pago | Cumplimiento empresarial | mend.io |
| Black Duck | Empresarial | Inteligencia profunda sobre licencias | synopsys.com |
| Sonatype Nexus | De pago | Políticas de licencias | sonatype.com |
| Snyk | Nivel gratuito | Seguridad + licencias unificadas | snyk.io |
Análisis rápido de licencias con Trivy:
# Scan for licenses
trivy fs --scanners license .
# Check for specific problematic licenses
trivy fs --scanners license --license-full .
GitHub Actions para el cumplimiento de licencias:
- name: License check
uses: fossas/fossa-action@main
with:
api-key: ${{ secrets.FOSSA_API_KEY }}
SBOM en el flujo de CI/CD
Integre la generación y el análisis de SBOM en su pipeline:
# Complete SBOM workflow
name: SBOM Pipeline
on:
push:
branches: [main]
release:
types: [published]
jobs:
sbom:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t myapp:${{ github.sha }} .
# Generate SBOM
- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
image: myapp:${{ github.sha }}
format: cyclonedx-json
output-file: sbom.json
# Scan for vulnerabilities
- name: Vulnerability scan
uses: anchore/scan-action@v3
with:
sbom: sbom.json
fail-build: true
severity-cutoff: high
# Check licenses
- name: License scan
run: |
trivy fs --scanners license --severity HIGH,CRITICAL . \
--exit-code 1
# Store SBOM with release
- name: Upload SBOM to release
if: github.event_name == 'release'
uses: softprops/action-gh-release@v1
with:
files: sbom.json
Mejores prácticas para SBOM
-
Genere con cada build. Los SBOMs deben ser artefactos versionados junto con sus lanzamientos.
-
Almacene los SBOMs con los lanzamientos. Adjúntelos a los releases de GitHub, guárdelos en el registro de artefactos o envíelos a Dependency-Track.
-
Automatice el análisis de vulnerabilidades. No solo genere — analice. Configure alertas para nuevos CVEs que afecten a sus componentes.
-
Defina políticas de licencias. Decida qué licencias son aceptables para su caso de uso. Bloquee los builds que introduzcan licencias problemáticas.
-
Comparta con los clientes. Si los clientes requieren SBOMs, automatice la entrega. No lo convierta en un proceso manual.
-
Monitorice continuamente. Se descubren nuevas vulnerabilidades cada día. Analice los SBOMs almacenados contra bases de datos de vulnerabilidades actualizadas.
DAST: pruebas dinámicas
Las herramientas DAST prueban las aplicaciones en ejecución enviando solicitudes y analizando respuestas. Detectan problemas que el análisis estático no puede ver: configuraciones incorrectas en tiempo de ejecución, omisiones de autenticación, problemas en las cabeceras de respuesta.
Qué detecta DAST
| Problema | Cómo lo detecta DAST |
|---|---|
| Cabeceras de seguridad faltantes | Comprueba las cabeceras de respuesta |
| XSS | Inyecta payloads, comprueba si se reflejan |
| Inyección SQL | Inyecta SQL, comprueba errores/cambios de comportamiento |
| Omisión de autenticación | Prueba el acceso sin credenciales válidas |
| Configuración CORS incorrecta | Prueba solicitudes de origen cruzado |
| Problemas SSL/TLS | Prueba el certificado, versiones de protocolo |
Herramienta: OWASP ZAP
ZAP (Zed Attack Proxy) es la herramienta DAST de código abierto estándar. Puede ejecutar análisis automatizados o usarse como proxy de interceptación para pruebas manuales.
Análisis en CI basado en Docker:
# GitHub Actions
name: DAST Scan
on:
push:
branches: [main]
jobs:
zap:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Start application
run: |
docker compose up -d
sleep 30 # Wait for app to start
- name: ZAP Baseline Scan
uses: zaproxy/action-[email protected]
with:
target: 'http://localhost:3000'
rules_file_name: '.zap/rules.tsv'
allow_issue_writing: false
Integración con GitLab CI:
dast:
stage: test
image: ghcr.io/zaproxy/zaproxy:stable
script:
- mkdir -p /zap/wrk
- zap-baseline.py -t $STAGING_URL -r report.html -I
artifacts:
paths:
- report.html
only:
- main
Análisis básico vs. análisis completo:
| Tipo de análisis | Duración | Cobertura | Caso de uso |
|---|---|---|---|
| Básico | 1-5 minutos | Comprobaciones pasivas, sin ataques | Cada despliegue |
| Completo | 30-60+ minutos | Ataques activos, exhaustivo | Semanal, antes de un lanzamiento |
Herramienta: Nuclei
Nuclei es rápido, basado en plantillas y excelente para comprobaciones de vulnerabilidades específicas.
Instalación:
# macOS/Linux
brew install nuclei
# or
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
Ejecutar análisis:
# Default templates
nuclei -u https://staging.example.com
# Specific severity
nuclei -u https://staging.example.com -severity high,critical
# Specific templates
nuclei -u https://staging.example.com -t cves/ -t misconfigurations/
Integración en CI:
nuclei:
stage: test
image: projectdiscovery/nuclei
script:
- nuclei -u $STAGING_URL -severity high,critical -o results.txt
artifacts:
paths:
- results.txt
Cuándo ejecutar DAST
DAST necesita una aplicación en ejecución, lo que complica la integración con CI/CD:
Opción 1: probar staging después del despliegue
deploy_staging:
stage: deploy
script:
- ./deploy-staging.sh
dast_scan:
stage: test
needs: [deploy_staging]
script:
- zap-baseline.py -t $STAGING_URL
Opción 2: crear un entorno efímero
dast:
stage: test
services:
- docker:dind
script:
- docker compose up -d
- sleep 30
- nuclei -u http://docker:3000 -severity critical
- docker compose down
Opción 3: análisis programados (no en el pipeline de PR)
# Run weekly, not on every commit
dast_weekly:
stage: security
script:
- zap-full-scan.py -t $PRODUCTION_URL -r report.html
only:
- schedules
Análisis IaC: infraestructura como código
Si usa Terraform, CloudFormation o manifiestos de Kubernetes, necesita análisis IaC. Las configuraciones incorrectas en el código de infraestructura son tan peligrosas como las vulnerabilidades de aplicaciones — buckets de S3 abiertos, roles IAM excesivamente permisivos, bases de datos sin cifrar.
Qué detecta el análisis IaC
| Problema | Ejemplo |
|---|---|
| Buckets S3 públicos | acl = "public-read" |
| IAM excesivamente permisivo | Action: "*", Resource: "*" |
| Almacenamiento sin cifrar | encrypted = true ausente |
| Grupos de seguridad abiertos | Ingress 0.0.0.0/0 |
| Registro faltante | CloudTrail, VPC flow logs deshabilitados |
| Secretos en el código | Claves de API en variables de Terraform |
Herramienta: Checkov
Checkov es el escáner IaC gratuito más completo. Soporta Terraform, CloudFormation, Kubernetes, Helm, ARM y más.
Instalación:
pip install checkov
Análisis local:
# Scan Terraform directory
checkov -d terraform/
# Scan specific file
checkov -f main.tf
# Output as JSON for CI
checkov -d terraform/ -o json
GitHub Actions:
- name: Checkov
uses: bridgecrewio/checkov-action@master
with:
directory: terraform/
soft_fail: false
skip_check: CKV_AWS_18,CKV_AWS_21 # Skip specific checks if needed
GitLab CI:
checkov:
stage: test
image: bridgecrew/checkov
script:
- checkov -d terraform/ --output cli --output junitxml --output-file-path console,results.xml
artifacts:
reports:
junit: results.xml
Herramienta: tfsec (específica para Terraform)
Si solo usa Terraform, tfsec es más rápido y está enfocado en Terraform.
Instalación:
brew install tfsec
Análisis:
tfsec terraform/
tfsec terraform/ --severity-override=HIGH,CRITICAL
GitHub Actions:
- name: tfsec
uses: aquasecurity/tfsec-[email protected]
with:
working_directory: terraform/
Gestión de hallazgos IaC
Los hallazgos IaC a menudo requieren contexto. Un «bucket S3 público» puede ser intencional (alojar un sitio web estático) o un problema crítico (almacenar datos de clientes).
Suprimir configuraciones intencionales:
# tfsec:ignore:aws-s3-no-public-access
resource "aws_s3_bucket" "website" {
# This bucket intentionally hosts public website
bucket = "company-website-assets"
}
# Checkov skip
resource "aws_s3_bucket" "website" {
#checkov:skip=CKV_AWS_18:This bucket hosts public website
bucket = "company-website-assets"
}
Integrando todo
Una configuración completa de análisis de seguridad para una aplicación web típica:
Ejemplo con GitHub Actions
name: Security Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
# SAST - runs on every commit
sast:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Semgrep
uses: semgrep/semgrep-action@v1
with:
config: p/security-audit p/secrets
# SCA - runs on every commit
sca:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: npm audit
run: npm audit --audit-level=high
- name: Snyk test
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=high
continue-on-error: true # Alert but don't block
# Container scanning - if building images
container:
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t app:${{ github.sha }} .
- name: Trivy scan
uses: aquasecurity/trivy-action@master
with:
image-ref: app:${{ github.sha }}
severity: 'CRITICAL,HIGH'
exit-code: '1'
# DAST - only on main branch after deploy
dast:
runs-on: ubuntu-latest
needs: [sast, sca]
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Deploy to staging
run: ./deploy-staging.sh
- name: ZAP Baseline
uses: zaproxy/action-[email protected]
with:
target: ${{ secrets.STAGING_URL }}
Ejemplo con GitLab CI
stages:
- test
- build
- security
- deploy
variables:
DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
# SAST
semgrep:
stage: test
image: semgrep/semgrep
script:
- semgrep ci --config auto
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
# SCA - dependencies
dependency_scan:
stage: test
image: node:20
script:
- npm ci
- npm audit --audit-level=high
allow_failure: true
# SCA - Snyk
snyk:
stage: test
image: snyk/snyk:node
script:
- snyk auth $SNYK_TOKEN
- snyk test --severity-threshold=high
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
# Build container
build:
stage: build
image: docker:latest
services:
- docker:dind
script:
- docker build -t $DOCKER_IMAGE .
- docker push $DOCKER_IMAGE
# Container scanning
trivy:
stage: security
image: aquasec/trivy
script:
- trivy image --exit-code 1 --severity HIGH,CRITICAL $DOCKER_IMAGE
needs: [build]
# DAST on staging
dast:
stage: security
image: ghcr.io/zaproxy/zaproxy:stable
script:
- zap-baseline.py -t $STAGING_URL -I
needs: [deploy_staging]
only:
- main
Cuando los escáneres detectan problemas: manual de respuesta del Security Champion
Su pipeline bloqueó un merge request. O peor — señaló algo en código que ya está en producción. ¿Qué hacer ahora?
Esta sección proporciona un enfoque estructurado para que los Security Champions gestionen los hallazgos de seguridad, desde la clasificación inicial hasta la resolución. El proceso sigue metodologías modernas de gestión de vulnerabilidades incluyendo CVSS, SSVC y VEX.
Paso 1: clasificación inicial (5-10 minutos)
Antes de profundizar, evalúe rápidamente con qué está tratando:
Reúna información básica:
| Pregunta | Dónde encontrarla |
|---|---|
| ¿Qué escáner lo detectó? | Salida del pipeline, nombre de la herramienta |
| ¿Qué tipo de hallazgo es? | ID del CVE, CWE, ID de la regla |
| ¿Dónde está? | Archivo, número de línea, dependencia |
| ¿Qué gravedad reporta la herramienta? | Crítico/Alto/Medio/Bajo |
| ¿Es código nuevo o existente? | Diferencia del PR, git blame |
Clasificación rápida:
Preguntas de clasificación inicial:
- ¿Es este un falso positivo conocido? → Sí: documéntelo y suprímalo (Paso 6). No: continúe al Paso 2.
- ¿Está esto en producción ahora mismo? → Sí: pista paralela — evalúe la exposición en producción (Paso 5). No: continúe el flujo normal.
- ¿Está bloqueando un despliegue crítico? → Sí: escale de inmediato, involucre a más personas. No: continúe metódicamente.
Paso 2: verificar el hallazgo (15-30 minutos)
No toda alerta del escáner es una vulnerabilidad real. Verifique antes de invertir más tiempo.
Para hallazgos SAST (vulnerabilidades de código):
- Lea el código señalado. Comprenda qué hace.
- Compruebe el flujo de datos. ¿La entrada del usuario realmente llega a este código?
- Rastree el origen de la entrada. ¿Se valida/sanitiza antes?
- Compruebe las protecciones existentes. Características de seguridad del framework, reglas WAF, validación de entrada.
# Example: Semgrep flags this as SQL injection
query = f"SELECT * FROM users WHERE id = {user_id}"
# Questions to answer:
# 1. Where does user_id come from? (request parameter? internal service?)
# 2. Is it validated before this line? (type check? allowlist?)
# 3. Is there a WAF or parameterization layer above?
Para hallazgos SCA (dependencias vulnerables):
- Compruebe si usa la función vulnerable. La mayoría de los CVEs afectan a características específicas.
- Lea la descripción del CVE. ¿Cuál es el vector de ataque?
- Compruebe su código. ¿Llama a la API vulnerable?
- Compruebe la exposición transitiva. ¿Otra dependencia usa la función vulnerable?
# Find where a dependency is used
grep -r "require('vulnerable-package')" src/
grep -r "from vulnerable_package import" src/
# Check if specific vulnerable function is called
grep -r "vulnerableFunction(" src/
Para hallazgos de contenedor/IaC:
- Compruebe si la configuración es intencional. Algunas configuraciones «inseguras» son válidas para su caso de uso.
- Verifique el riesgo real. ¿Está expuesto el recurso? ¿Hay un control compensatorio?
- Compruebe en tiempo de ejecución vs. en build. Algunos hallazgos solo importan en entornos específicos.
Resultado de la verificación:
| Resultado | Acción |
|---|---|
| Vulnerabilidad confirmada | Continúe al Paso 3 |
| Falso positivo | Documente y suprima (Paso 6) |
| Incierto | Pida una segunda opinión, trátelo como real por defecto |
Paso 3: evaluar la explotabilidad (15-45 minutos)
Una vulnerabilidad confirmada no es necesariamente explotable en su contexto. Evalúe el riesgo real.
Factores de explotabilidad (basados en CVSS v4.0):
| Factor | Preguntas a responder |
|---|---|
| Vector de ataque | ¿Accesible por red? ¿Solo local? ¿Necesita acceso físico? |
| Complejidad del ataque | ¿Fácil de explotar? ¿Requiere condiciones específicas? |
| Privilegios requeridos | ¿Anónimo? ¿Usuario autenticado? ¿Administrador? |
| Interacción del usuario | ¿Ninguna? ¿La víctima debe hacer clic en un enlace? |
Evaluación específica del contexto:
| Factor | Preguntas a responder |
|---|---|
| Exposición | ¿Es este código/componente accesible desde Internet? |
| Sensibilidad de los datos | ¿A qué datos se podría acceder si se explota? |
| Controles existentes | ¿WAF, limitación de velocidad, autenticación, segmentación de red? |
| Disponibilidad del exploit | ¿Exploit público? ¿Módulo de Metasploit? ¿Solo teórico? |
Comprobación rápida de explotabilidad:
# Check if a public exploit exists
searchsploit CVE-2024-XXXXX
# Check ExploitDB
curl -s "https://www.exploit-db.com/search?cve=2024-XXXXX"
# Check CISA KEV (Known Exploited Vulnerabilities)
curl -s https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json | \
jq '.vulnerabilities[] | select(.cveID=="CVE-2024-XXXXX")'
Matriz de explotabilidad:
| Exploit disponible | Accesible externamente | Datos sensibles en riesgo | Prioridad |
|---|---|---|---|
| Sí | Sí | Sí | CRÍTICO — Acción inmediata |
| Sí | Sí | No | ALTO — Corregir este sprint |
| Sí | No | Sí | ALTO — Corregir este sprint |
| No | Sí | Sí | MEDIO — Corregir pronto |
| No | No | No | BAJO — Registrar, corregir cuando sea conveniente |
Paso 4: determinar el impacto empresarial (10-20 minutos)
La gravedad técnica ≠ impacto empresarial. Un CVE crítico en una herramienta de desarrollo importa menos que un problema medio en su sistema de pagos.
Preguntas de evaluación de impacto:
| Categoría | Preguntas |
|---|---|
| Confidencialidad | ¿Qué datos podrían filtrarse? ¿PII? ¿Credenciales? ¿Secretos empresariales? |
| Integridad | ¿Podrían modificarse datos? ¿Registros financieros? ¿Permisos de usuario? |
| Disponibilidad | ¿Podría caer el sistema? ¿Durante cuánto tiempo? |
| Cumplimiento | ¿Infringe regulaciones? ¿GDPR, PCI DSS, HIPAA? |
| Reputación | ¿Sería noticia si se explotara? |
Calcular la prioridad (inspirado en SSVC):
Puntúe cada factor y sume el resultado:
- Explotación — Activa en el mundo real: +2 / PoC existe: +1 / Ninguna conocida: +0
- Exposición — Con acceso a Internet sin autenticación: +2 / Autenticado: +1 / Solo interno: +0
- Impacto — Compromiso total del sistema: +2 / Acceso o modificación de datos: +1 / Limitado: +0
Total: 5–6 → Inmediato | 3–4 → Urgente | 1–2 → Programado
Paso 5: comprobar la exposición en producción (pista paralela)
Si el código/componente vulnerable está en producción, necesita saberlo de inmediato.
Preguntas a responder:
-
¿Está la vulnerabilidad en producción?
- Compruebe las versiones desplegadas
- Compruebe el historial de lanzamientos
- ¿Cuándo se introdujo?
-
¿Ha sido explotada?
- Compruebe los registros de la aplicación en busca de patrones sospechosos
- Compruebe los registros del WAF en busca de firmas de ataque
- Compruebe los registros de acceso en busca de anomalías
- Compruebe las alertas del SIEM
-
¿Cuál es el radio de explosión?
- ¿Qué entornos están afectados?
- ¿Qué clientes/usuarios?
- ¿Cuánto tiempo ha estado expuesto?
Lista de verificación para investigación en producción:
# Check if vulnerable version is deployed
kubectl get deployments -o jsonpath='{.items[*].spec.template.spec.containers[*].image}'
# Search logs for exploit patterns (example for SQL injection)
grep -E "(UNION|SELECT.*FROM|DROP TABLE|--|;)" /var/log/app/*.log
# Check for unusual error rates
grep "500\|502\|503" /var/log/nginx/access.log | wc -l
# Check authentication failures spike
grep "authentication failed" /var/log/app/*.log | \
awk '{print $1}' | sort | uniq -c | sort -rn | head -20
Si se sospecha explotación:
- Contenga de inmediato — Deshabilite la función afectada, bloquee las IPs, rote credenciales
- Preserve la evidencia — No elimine los registros, tome snapshots
- Active la respuesta a incidentes — Esto es ahora un incidente de seguridad, no solo una vulnerabilidad
- Notifique a las partes interesadas — Dirección, legal, cumplimiento según corresponda
Paso 6: decidir y actuar
Basándose en su evaluación, elija la respuesta apropiada:
Opciones de respuesta:
| Prioridad | Respuesta | Plazo | Quién decide |
|---|---|---|---|
| Inmediato | Bloquear merge, hotfix en producción | Horas | Security Champion + Lead |
| Urgente | Corregir en el sprint actual, parche en producción programado | Días | Security Champion |
| Programado | Añadir al backlog, corregir en el desarrollo normal | Semanas | Security Champion |
| Aceptar riesgo | Documentar decisión, implementar monitorización | N/A | Security Champion + Dirección |
| Falso positivo | Suprimir con documentación | Inmediato | Security Champion |
Para vulnerabilidades confirmadas — flujo de corrección:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Create │────►│ Implement │────►│ Verify │────►│ Deploy │
│ ticket │ │ fix │ │ fix │ │ + close │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
│ │ │ │
▼ ▼ ▼ ▼
- CVE/CWE ID - Code change - Run scanner - Deploy to prod
- Severity - Dependency - Manual verify - Monitor for issues
- Impact analysis update - Regression - Update SBOM
- Affected versions - Config fix tests - Close ticket
Para falsos positivos — flujo de supresión:
# 1. Document WHY it's a false positive
# semgrep: .semgrepignore or inline
def process_data(data):
# nosemgrep: sql-injection
# Reason: 'data' is validated UUID from internal service, not user input
query = f"SELECT * FROM cache WHERE id = '{data}'"
# 2. Add to team knowledge base
# Create entry in security wiki explaining this pattern
# 3. Consider improving the rule
# Report to Semgrep community if rule has high false positive rate
Para riesgos aceptados:
## Risk Acceptance Record
**Vulnerability:** CVE-2024-XXXXX in package-name v1.2.3
**Date:** 2024-12-28
**Decided by:** [Name], approved by [Manager]
### Risk assessment
- Severity: HIGH (CVSS 8.1)
- Exploitability in our context: LOW
- Reason: Vulnerable function not used in our codebase
### Mitigating controls
- [ ] WAF rule blocks attack pattern
- [ ] Input validation in place
- [ ] Monitoring for exploitation attempts
### Review schedule
- Next review: 2025-03-28
- Trigger for re-review: New exploit published, or mitigating control removed
### Acceptance signature
Accepted by: _____________ Date: _____________
Paso 7: prevenir la recurrencia
Después de corregir, evite que el mismo problema vuelva a aparecer.
Acciones:
- Añadir reglas específicas al escáner — Si es un patrón de código personalizado, añada una regla de Semgrep
- Actualizar la política de dependencias — Bloquear versiones vulnerables en el lockfile
- Añadir a la formación de seguridad — Compartir como caso de estudio con el equipo
- Mejorar la detección — Si se detectó tarde, mejorar la cobertura del análisis
Ejemplo: prevenir el uso futuro de un patrón vulnerable:
# .semgrep.yml - custom rule to prevent pattern
rules:
- id: no-string-format-sql
patterns:
- pattern: f"SELECT ... {$VAR} ..."
message: "Use parameterized queries, not string formatting"
languages: [python]
severity: ERROR
Tiempos de respuesta recomendados
| Prioridad | Respuesta inicial | Corrección implementada | Parche en producción |
|---|---|---|---|
| Inmediato (exploit activo, datos críticos) | 1 hora | 4 horas | 8 horas |
| Urgente (exploit público, exposición externa) | 4 horas | 24 horas | 48 horas |
| Programado (sin exploit, exposición limitada) | 24 horas | 1-2 semanas | Próximo lanzamiento |
| Bajo (teórico, sin exposición) | 1 semana | 1-2 meses | Cuando sea conveniente |
Matriz de escalación
| Situación | Escalar a | Método |
|---|---|---|
| Explotación activa en curso | CTO, Respuesta a incidentes, Legal | Llamada telefónica |
| Vulnerabilidad crítica en producción | Engineering Lead, CTO | Slack + llamada |
| Incertidumbre sobre gravedad/explotabilidad | Ingeniero senior, consultor externo | Slack |
| Aceptación de riesgo necesaria | Engineering Manager | Email con documentación |
| Parche de proveedor requerido | Contacto de seguridad del proveedor | Email, ticket de soporte |
Plantilla de documentación
Use esta plantilla para cada hallazgo significativo:
## Security Finding Report
### Summary
- **Finding ID:** [JIRA/ticket number]
- **Scanner:** [Semgrep/Snyk/Trivy/etc]
- **Rule/CVE:** [Rule ID or CVE number]
- **Severity (tool):** [Critical/High/Medium/Low]
- **Severity (assessed):** [After your analysis]
- **Status:** [New/Investigating/Confirmed/Fixed/False Positive/Accepted]
### Technical details
- **Location:** [file:line or package:version]
- **Introduced:** [commit/date/PR]
- **In production:** [Yes/No, since when]
### Analysis
- **Verification result:** [Confirmed/False positive]
- **Exploitability:** [High/Medium/Low/None]
- **Attack vector:** [Description]
- **Existing controls:** [WAF/validation/etc]
### Impact
- **Confidentiality:** [None/Low/High]
- **Integrity:** [None/Low/High]
- **Availability:** [None/Low/High]
- **Business impact:** [Description]
### Resolution
- **Action taken:** [Fix/Accept/Suppress]
- **Fix PR:** [Link]
- **Deployed:** [Date]
- **Verified:** [How]
### Prevention
- **New scanner rule:** [Yes/No, link]
- **Training update:** [Yes/No]
- **Process change:** [Description]
Errores comunes
Bloquear todo
# BAD: Every finding blocks the build
- run: npm audit # Fails on ANY vulnerability
Esto lleva a pipelines ignorados, controles deshabilitados o cultura de «corregir después».
# GOOD: Block on critical, warn on medium
- run: npm audit --audit-level=critical
No bloquear nada
# BAD: Scan runs but never fails
- run: semgrep --config auto || true
Los hallazgos de seguridad se acumulan, nadie mira los informes.
# GOOD: Block on high severity
- run: semgrep --config auto --error --severity=ERROR
Ejecutar DAST en producción
# BAD: Attacking your own production
- run: zap-full-scan.py -t https://production.example.com
Los análisis DAST completos pueden romper cosas. Use staging.
# GOOD: Attack staging only
- run: zap-full-scan.py -t $STAGING_URL
Ignorar la salida de las herramientas
Configurar el análisis sin un proceso para gestionar los hallazgos. Las herramientas detectan problemas → nadie los clasifica → las alertas se ignoran → las herramientas se deshabilitan.
Solución: Asigne responsabilidad. Alguien revisa los hallazgos semanalmente. Los problemas críticos crean tickets. Los problemas medios se revisan mensualmente.
Demasiadas herramientas
Ejecutar cinco herramientas SAST diferentes, tres escáneres SCA y esperar que más sea mejor. Resultado: ruido, hallazgos duplicados, pipelines lentos.
Solución: Comience con una herramienta por categoría. Añada más solo si tiene carencias específicas.
Analizar solo en main
# BAD: Issues found after merge
only:
- main
Detecte los problemas en los PRs, no después de que se hayan mezclado.
# GOOD: Scan on every PR
on:
push:
branches: [main]
pull_request: # This is key
Incidentes reales
Ataque a la cadena de suministro de Codecov (2021). Los atacantes comprometieron el script bash uploader de Codecov utilizado en miles de pipelines de CI/CD. Durante más de dos meses, el script modificado exfiltró variables de entorno — incluyendo secretos de CI, tokens de API y credenciales — de cada pipeline que lo usaba. Empresas como Twilio, HashiCorp y Confluent se vieron afectadas.
Secuestro de ua-parser-js (2021). Un popular paquete npm (8 millones de descargas semanales) fue secuestrado cuando un atacante comprometió la cuenta npm del maintainer. Las versiones maliciosas minaban criptomonedas y robaban contraseñas. Los proyectos con análisis SCA detectaron el problema en horas; los que no lo tenían distribuyeron builds comprometidos.
Log4Shell (2021). CVE-2021-44228 en Log4j afectó a prácticamente todas las aplicaciones Java. Las organizaciones con análisis SCA conocieron su exposición en horas. Las que no tenían análisis tardaron días en averiguar qué aplicaciones usaban Log4j y qué versiones. La diferencia entre «estamos parcheados» y «seguimos investigando» fue el análisis automatizado de dependencias.
Estos incidentes comparten un patrón: las organizaciones con análisis automatizado detectaron y respondieron más rápido. Las que no lo tenían se vieron abrumadas.
Taller: proteja su pipeline
Reserve 2-3 horas para este ejercicio.
Parte 1: añadir análisis SAST (30 minutos)
Para GitHub:
- Cree
.github/workflows/security.yml:
name: Security Scan
on:
push:
branches: [main]
pull_request:
jobs:
semgrep:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: semgrep/semgrep-action@v1
with:
config: p/security-audit p/secrets
- Haga commit y push
- Cree un PR de prueba y verifique que el análisis se ejecuta
- Revise los hallazgos
Para GitLab:
- Añada a
.gitlab-ci.yml:
semgrep:
stage: test
image: semgrep/semgrep
script:
- semgrep ci --config auto
- Haga commit y push
- Verifique que el análisis se ejecuta en el pipeline
- Revise los hallazgos en la salida del pipeline
Entregable: Análisis SAST funcionando en CI
Parte 2: configurar Dependabot o Snyk (30 minutos)
Opción A — Dependabot (GitHub):
- Cree
.github/dependabot.yml:
version: 2
updates:
- package-ecosystem: "npm" # or pip, bundler, etc.
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
- Vaya a Settings → Security → Active las alertas y actualizaciones de seguridad de Dependabot
- Revise las alertas existentes en la pestaña Security
Opción B — Snyk:
- Regístrese en snyk.io (nivel gratuito)
- Instale la CLI:
npm install -g snyk - Autentíquese:
snyk auth - Ejecute el análisis inicial:
snyk test - Añada a CI (vea los ejemplos anteriores)
Entregable: Análisis de dependencias habilitado con los hallazgos iniciales revisados
Parte 3: añadir análisis de contenedores (30 minutos)
Si usa Docker:
- Añada Trivy a su flujo de trabajo:
container-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: docker build -t myapp:test .
- uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:test
severity: 'CRITICAL,HIGH'
- Construya su imagen localmente y analícela:
docker build -t myapp:test .
trivy image myapp:test
- Revise los hallazgos y corrija los problemas críticos
Entregable: Análisis de contenedores en CI con vulnerabilidades de imagen base documentadas
Parte 4: configurar DAST de base (30 minutos)
-
Despliegue su aplicación en un entorno de staging (o ejecútela localmente)
-
Ejecute el análisis de base de ZAP:
docker run -t ghcr.io/zaproxy/zaproxy:stable zap-baseline.py \
-t http://your-staging-url
-
Revise la salida — compruebe:
- Cabeceras de seguridad faltantes
- Problemas de seguridad en cookies
- Divulgación de información
-
Añada el análisis de base al pipeline de CI (solo staging)
Entregable: Análisis DAST de base configurado para staging
Parte 5: añadir análisis IaC (20 minutos)
Si usa Terraform, CloudFormation o Kubernetes:
- Instale Checkov:
pip install checkov
- Analice su código de infraestructura:
checkov -d terraform/ # or cloudformation/, k8s/
- Añada a CI:
# GitHub Actions
- name: Checkov
uses: bridgecrewio/checkov-action@master
with:
directory: terraform/
soft_fail: false
- Revise los hallazgos y corrija las configuraciones incorrectas críticas
Entregable: Análisis IaC en CI con los principales problemas documentados
Parte 6: configurar la generación de SBOM (20 minutos)
- Instale Syft:
brew install syft
# or
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
- Genere un SBOM para su proyecto:
syft dir:. -o cyclonedx-json > sbom.json
- Analice el SBOM en busca de vulnerabilidades:
brew install grype
grype sbom:sbom.json
- Añada a CI:
# GitHub Actions
- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
path: .
format: cyclonedx-json
output-file: sbom.json
- name: Scan SBOM
uses: anchore/scan-action@v3
with:
sbom: sbom.json
fail-build: true
severity-cutoff: high
- Revise la información de licencias en el SBOM
Entregable: Generación y análisis de SBOM en CI
Parte 7: crear el proceso de clasificación (30 minutos)
Cree un documento simple:
# Security Findings Triage Process
## Severity levels
- **Critical/High**: Block merge, fix immediately
- **Medium**: Fix in current sprint
- **Low**: Add to backlog, fix when convenient
## Who triages
- [Name] reviews findings weekly
- Critical findings notify #security-alerts channel
## False positives
- Document in `.semgrep.yml` or tool config
- Require approval from [Name] to suppress
## Metrics tracked
- Open findings by severity
- Time from finding to fix
- Findings per deployment
Entregable: Proceso de clasificación documentado
Artefactos de este capítulo
Al finalizar este capítulo, debería tener:
- Escáner SAST configurado — Semgrep o CodeQL ejecutándose en cada PR
- Dependabot/Snyk habilitado — Análisis de dependencias con alertas configuradas
- Análisis de contenedores — Trivy analizando imágenes Docker (si aplica)
- Análisis IaC — Checkov o tfsec analizando código de infraestructura (si aplica)
- Generación de SBOM — Syft generando SBOMs con cada build
- Base DAST — ZAP o Nuclei ejecutándose en los despliegues de staging
- Archivo del flujo de trabajo de seguridad — Configuración completa del pipeline de seguridad CI/CD
- Manual de respuesta a hallazgos — Proceso paso a paso para gestionar los hallazgos de los escáneres
- Matriz de escalación — A quién contactar para diferentes niveles de gravedad
- Documento del proceso de clasificación — Cómo se priorizan y asignan los hallazgos
Cómo explicarlo a la dirección
Cuando alguien pregunta por qué está añadiendo análisis de seguridad a CI/CD:
«Estoy añadiendo comprobaciones de seguridad automatizadas a nuestro pipeline de despliegue. Estas herramientas analizan nuestro código en busca de vulnerabilidades, comprueban nuestras dependencias en busca de problemas de seguridad conocidos y prueban la aplicación en ejecución ante vectores de ataque comunes. Detectan los problemas antes de que lleguen a producción — inyección SQL, bibliotecas vulnerables, servidores mal configurados. Las herramientas son gratuitas y añaden unos 2-3 minutos a nuestro pipeline. La alternativa es encontrar estos problemas después de una brecha, lo que es significativamente más costoso en dinero y reputación.»
Versión corta: «Estoy añadiendo comprobaciones de seguridad automatizadas para detectar vulnerabilidades antes que los atacantes.»
Autoevaluación
Análisis estático (SAST)
- Semgrep o CodeQL ejecutándose en cada PR
- Los hallazgos de alta gravedad bloquean el merge
- Proceso de supresión de falsos positivos documentado
- El equipo sabe cómo leer los hallazgos SAST
Análisis de dependencias (SCA)
- Dependabot o Snyk habilitado
- Alertas configuradas y siendo revisadas
- Vulnerabilidades críticas en dependencias corregidas
- Proceso para gestionar vulnerabilidades sin solución
Análisis de contenedores
- Trivy analizando imágenes antes de enviarlas al registro
- Imágenes base actualizadas para corregir vulnerabilidades críticas
- Análisis integrado en el pipeline de build
Infraestructura como código (IaC)
- Checkov o tfsec ejecutándose en cambios de infraestructura
- Configuraciones incorrectas críticas (buckets públicos, grupos de seguridad abiertos) bloqueadas
- Excepciones intencionales documentadas con comentarios de skip
SBOM (Software Bill of Materials)
- SBOM generado para cada lanzamiento
- SBOMs analizados en busca de vulnerabilidades
- Política de licencias definida (licencias aceptables/bloqueadas)
- SBOMs almacenados con los artefactos de lanzamiento
Pruebas dinámicas (DAST)
- Análisis de base ejecutándose en staging
- Cabeceras de seguridad comprobadas
- Análisis completo programado (semanal o antes de un lanzamiento)
Proceso de respuesta a hallazgos
- Manual de respuesta a hallazgos documentado
- Matriz de escalación definida
- Proceso de aceptación de riesgo establecido
- Plantilla de documentación de hallazgos en uso
Proceso
- Alguien es responsable de la clasificación de hallazgos de seguridad
- Umbrales de gravedad definidos
- Métricas siendo rastreadas
Marque al menos 18 de 28 elementos antes de continuar.
Referencia de herramientas de análisis de seguridad
Esta sección proporciona una lista completa de herramientas de análisis de seguridad, organizadas de gratuitas/simples a empresariales/complejas. Comience con el nivel gratuito — cubre la mayoría de las necesidades. Pase a herramientas de pago cuando necesite características específicas, mejor soporte o cumplimiento empresarial.
Herramientas SAST (análisis estático de código)
| Herramienta | Precio | Lenguajes | Mejor para | Enlace |
|---|---|---|---|---|
| Semgrep | Gratuito (código abierto) | 30+ lenguajes | General, reglas personalizadas | semgrep.dev |
| Bandit | Gratuito (código abierto) | Python | Seguridad específica de Python | GitHub |
| gosec | Gratuito (código abierto) | Go | Seguridad específica de Go | GitHub |
| Brakeman | Gratuito (código abierto) | Ruby/Rails | Aplicaciones Rails | brakemanscanner.org |
| ESLint security | Gratuito (código abierto) | JavaScript | Reglas de seguridad JS/Node.js | GitHub |
| Psalm | Gratuito (código abierto) | PHP | Comprobación de tipos + seguridad PHP | psalm.dev |
| PHPStan | Gratuito (código abierto) | PHP | Análisis estático PHP | phpstan.org |
| CodeQL | Gratuito para repos públicos | 10+ lenguajes | Análisis semántico profundo | GitHub |
| SonarQube Community | Gratuito (autoalojado) | 30+ lenguajes | Calidad de código + seguridad | sonarsource.com |
| Semgrep Pro | De pago | 30+ lenguajes | Reglas avanzadas, funciones de equipo | semgrep.dev |
| SonarCloud | Gratuito para público, de pago para privado | 30+ lenguajes | SonarQube en la nube | sonarcloud.io |
| Snyk Code | Nivel gratuito, planes de pago | 10+ lenguajes | Impulsado por IA, rápido | snyk.io |
| Checkmarx | Empresarial | 30+ lenguajes | Cumplimiento empresarial | checkmarx.com |
| Veracode | Empresarial | 30+ lenguajes | Empresarial, análisis binario | veracode.com |
| Fortify | Empresarial | 30+ lenguajes | Empresarial, on-premise | microfocus.com |
Recomendación para equipos pequeños: Comience con Semgrep (gratuito, rápido, buenas reglas). Añada CodeQL si está en GitHub. Considere Snyk Code si necesita más cobertura.
Herramientas SCA (análisis de dependencias)
| Herramienta | Precio | Ecosistemas | Mejor para | Enlace |
|---|---|---|---|---|
| npm audit | Gratuito (integrado) | npm | Proyectos Node.js | docs.npmjs.com |
| pip-audit | Gratuito (código abierto) | pip | Proyectos Python | GitHub |
| bundle-audit | Gratuito (código abierto) | bundler | Proyectos Ruby | GitHub |
| govulncheck | Gratuito (oficial) | Go modules | Proyectos Go | pkg.go.dev |
| composer audit | Gratuito (integrado) | Composer | Proyectos PHP | getcomposer.org |
| Dependabot | Gratuito (integrado en GitHub) | 15+ ecosistemas | Repositorios GitHub | GitHub |
| Trivy | Gratuito (código abierto) | Todos los principales + contenedores | Escáner universal | trivy.dev |
| Grype | Gratuito (código abierto) | Todos los principales + contenedores | Rápido, soporte SBOM | GitHub |
| OSV-Scanner | Gratuito (Google) | Todos los principales | Base de datos OSV de Google | GitHub |
| OWASP Dependency-Check | Gratuito (código abierto) | Java, .NET, JS, Ruby | Proyecto OWASP | owasp.org |
| Renovate | Gratuito (código abierto) | 50+ ecosistemas | Actualizaciones de dependencias | GitHub |
| Snyk Open Source | Nivel gratuito, planes de pago | Todos los principales | Mejores sugerencias de corrección | snyk.io |
| Mend (WhiteSource) | De pago | Todos los principales | Cumplimiento de licencias | mend.io |
| Black Duck | Empresarial | Todos los principales | Cumplimiento empresarial | synopsys.com |
| JFrog Xray | De pago | Todos los principales | Integración con repositorio de artefactos | jfrog.com |
Recomendación para equipos pequeños: Use Dependabot (gratuito en GitHub) o Renovate. Añada Trivy para contenedores. El nivel gratuito de Snyk es excelente si necesita más visibilidad.
Herramientas DAST (pruebas dinámicas)
| Herramienta | Precio | Tipo | Mejor para | Enlace |
|---|---|---|---|---|
| OWASP ZAP | Gratuito (código abierto) | DAST completo | Pruebas generales de aplicaciones web | zaproxy.org |
| Nuclei | Gratuito (código abierto) | Basado en plantillas | Rápido, comprobaciones de CVE específicos | nuclei.projectdiscovery.io |
| Nikto | Gratuito (código abierto) | Escáner de servidor web | Configuraciones incorrectas de servidor | GitHub |
| wapiti | Gratuito (código abierto) | Escáner de aplicación web | Pruebas de caja negra | GitHub |
| Arachni | Gratuito (código abierto) | DAST completo | Escáner con muchas funciones | GitHub |
| sqlmap | Gratuito (código abierto) | Inyección SQL | Pruebas de inyección SQL | sqlmap.org |
| StackHawk | Nivel gratuito, planes de pago | Enfocado en API | APIs modernas, nativo para CI/CD | stackhawk.com |
| Burp Suite Community | Gratuito | Pruebas manuales | Pruebas de seguridad manuales | portswigger.net |
| Burp Suite Pro | 449$/año | DAST completo | Pruebas de penetración profesionales | portswigger.net |
| Acunetix | De pago | DAST completo | Análisis web automatizado | acunetix.com |
| Invicti (Netsparker) | Empresarial | DAST completo | Aplicaciones web empresariales | invicti.com |
| Qualys WAS | Empresarial | DAST completo | Empresarial, cumplimiento | qualys.com |
Recomendación para equipos pequeños: Comience con análisis de base de ZAP en CI. Añada Nuclei para comprobaciones específicas de CVE. Burp Suite Community para pruebas manuales.
Análisis de contenedores e imágenes
| Herramienta | Precio | Características | Mejor para | Enlace |
|---|---|---|---|---|
| Trivy | Gratuito (código abierto) | Imágenes, IaC, SBOM | Escáner universal | trivy.dev |
| Grype | Gratuito (código abierto) | Imágenes, SBOM | Rápido, ecosistema Anchore | GitHub |
| Clair | Gratuito (código abierto) | Imágenes | Registros de contenedores | GitHub |
| Syft | Gratuito (código abierto) | Generación de SBOM | Software Bill of Materials | GitHub |
| Docker Scout | Nivel gratuito | Imágenes | Integración con Docker Hub | docker.com |
| Snyk Container | Nivel gratuito, planes de pago | Imágenes, Kubernetes | Recomendaciones de corrección | snyk.io |
| Anchore Enterprise | De pago | Imágenes, políticas | Cumplimiento empresarial | anchore.com |
| Sysdig Secure | De pago | Runtime + análisis | Seguridad en tiempo de ejecución | sysdig.com |
| Prisma Cloud | Empresarial | CNAPP completo | Seguridad cloud-native | paloaltonetworks.com |
Recomendación para equipos pequeños: Trivy hace todo lo que necesita de forma gratuita. Añada Docker Scout si está en Docker Hub.
Análisis de infraestructura como código (IaC)
| Herramienta | Precio | IaC soportado | Mejor para | Enlace |
|---|---|---|---|---|
| Checkov | Gratuito (código abierto) | Terraform, CloudFormation, K8s, ARM | Análisis IaC completo | checkov.io |
| tfsec | Gratuito (código abierto) | Terraform | Enfocado en Terraform | GitHub |
| Terrascan | Gratuito (código abierto) | Terraform, K8s, Helm, Dockerfile | Política como código | GitHub |
| KICS | Gratuito (código abierto) | 15+ plataformas IaC | Cobertura amplia | kics.io |
| cfn-lint | Gratuito (oficial AWS) | CloudFormation | AWS CloudFormation | GitHub |
| cfn_nag | Gratuito (código abierto) | CloudFormation | Seguridad en CloudFormation | GitHub |
| kubesec | Gratuito (código abierto) | Kubernetes | Seguridad de manifiestos K8s | kubesec.io |
| Trivy | Gratuito (código abierto) | Terraform, K8s, Dockerfile | Universal (IaC + contenedores) | trivy.dev |
| Snyk IaC | Nivel gratuito, planes de pago | Terraform, K8s, CloudFormation | Recomendaciones de corrección | snyk.io |
| Bridgecrew | De pago (ahora Prisma Cloud) | Todos los principales | Empresarial, backend Checkov | paloaltonetworks.com |
Recomendación para equipos pequeños: Comience con Checkov — es completo y gratuito. tfsec es excelente si solo usa Terraform.
Análisis IaC en CI:
# GitHub Actions - Checkov
- name: Checkov
uses: bridgecrewio/checkov-action@master
with:
directory: terraform/
framework: terraform
soft_fail: false
# GitLab CI - tfsec
tfsec:
stage: test
image: aquasec/tfsec:latest
script:
- tfsec terraform/ --severity-override=HIGH,CRITICAL
Generación y análisis de SBOM
| Herramienta | Precio | Tipo | Mejor para | Enlace |
|---|---|---|---|---|
| Syft | Gratuito (código abierto) | Generación de SBOM | Generador universal | GitHub |
| cdxgen | Gratuito (código abierto) | Generación de SBOM | Formato CycloneDX | GitHub |
| Trivy | Gratuito (código abierto) | SBOM + análisis | Todo en uno | trivy.dev |
| Grype | Gratuito (código abierto) | Análisis de vulnerabilidades SBOM | Análisis rápido | GitHub |
| OSV-Scanner | Gratuito (Google) | Análisis de vulnerabilidades SBOM | Base de datos de Google | GitHub |
| OWASP Dependency-Track | Gratuito (autoalojado) | Plataforma SBOM | Gestión completa | dependencytrack.org |
| FOSSA | Nivel gratuito, planes de pago | Cumplimiento de licencias | Análisis profundo de licencias | fossa.com |
| Anchore Enterprise | De pago | Plataforma SBOM | Políticas empresariales | anchore.com |
| Sonatype Nexus | De pago | SBOM + cumplimiento | Integración con repositorio | sonatype.com |
Recomendación para equipos pequeños: Use Syft para generar SBOMs, Grype para analizar vulnerabilidades. Añada OWASP Dependency-Track si necesita seguimiento centralizado.
Análisis de secretos
| Herramienta | Precio | Características | Mejor para | Enlace |
|---|---|---|---|---|
| gitleaks | Gratuito (código abierto) | Historial git, pre-commit | Rápido, configurable | gitleaks.io |
| truffleHog | Gratuito (código abierto) | Git, S3, GCS, secretos verificados | Análisis profundo | GitHub |
| git-secrets | Gratuito (AWS) | Hooks pre-commit | Credenciales AWS | GitHub |
| detect-secrets | Gratuito (código abierto) | Enfoque de línea base | Herramienta de Yelp | GitHub |
| GitHub Secret Scanning | Gratuito (integrado en GitHub) | Protección en push | Repositorios GitHub | docs.github.com |
| GitLab Secret Detection | Gratuito (integrado en GitLab) | Integración en pipeline | Repositorios GitLab | docs.gitlab.com |
| GitGuardian | Gratuito para individuos | Monitorización en tiempo real | Amigable para desarrolladores | gitguardian.com |
| Snyk | Nivel gratuito | Parte de Snyk Code | Plataforma unificada | snyk.io |
Recomendación para equipos pequeños: Active el análisis integrado de GitHub/GitLab. Añada gitleaks como hook pre-commit. Vea el capítulo de gestión de secretos para la configuración detallada.
Pruebas de seguridad de API
| Herramienta | Precio | Tipo | Mejor para | Enlace |
|---|---|---|---|---|
| OWASP ZAP | Gratuito (código abierto) | Análisis OpenAPI/Swagger | APIs REST | zaproxy.org |
| Nuclei | Gratuito (código abierto) | Basado en plantillas | Comprobaciones de CVE en API | nuclei.projectdiscovery.io |
| Postman | Nivel gratuito | Plataforma de pruebas de API | Manual + automatizado | postman.com |
| StackHawk | Nivel gratuito, planes de pago | DAST enfocado en API | APIs modernas, GraphQL | stackhawk.com |
| Akto | Nivel gratuito | Descubrimiento + pruebas de API | Inventario de API | akto.io |
| 42Crunch | De pago | Seguridad OpenAPI | Plataforma de seguridad de API | 42crunch.com |
| Salt Security | Empresarial | Protección de API en runtime | Detección de amenazas en API | salt.security |
| Noname Security | Empresarial | Seguridad de API completa | APIs empresariales | nonamesecurity.com |
Recomendación para equipos pequeños: Use ZAP con importación OpenAPI. Añada StackHawk si necesita mejor soporte para APIs.
Plataformas todo en uno
Estas plataformas combinan múltiples tipos de análisis en una sola solución:
| Plataforma | Incluye | Precio | Mejor para | Enlace |
|---|---|---|---|---|
| GitHub Advanced Security | SAST (CodeQL), SCA, Secretos | 49$/usuario/mes | Equipos nativos de GitHub | github.com |
| GitLab Ultimate | SAST, SCA, DAST, Secretos, Contenedor | 99$/usuario/mes | Equipos nativos de GitLab | gitlab.com |
| Snyk | SAST, SCA, Contenedor, IaC | Nivel gratuito, planes de pago | Amigable para desarrolladores | snyk.io |
| Sonar | SAST, calidad de código | Nivel gratuito (Cloud), de pago | Enfoque en calidad de código | sonarsource.com |
| Veracode | SAST, SCA, DAST | Empresarial | Grandes empresas | veracode.com |
| Checkmarx One | SAST, SCA, DAST, IaC | Empresarial | Cumplimiento empresarial | checkmarx.com |
| Synopsys | SAST, SCA, DAST | Empresarial | Empresarial, legacy | synopsys.com |
Recomendación para equipos pequeños: Si está en GitHub, active primero las funciones gratuitas, luego considere GitHub Advanced Security. El nivel gratuito de Snyk es generoso y cubre la mayoría de las necesidades. Evite las plataformas empresariales hasta que realmente necesite funciones empresariales.
Inicio rápido: pipeline de seguridad mínimo viable
Si está empezando, aquí está la configuración mínima usando solo herramientas gratuitas:
| Categoría | Herramienta | Por qué |
|---|---|---|
| SAST | Semgrep | Rápido, buenas reglas, gratuito |
| SCA | Dependabot o Trivy | Integrado o universal |
| Secretos | gitleaks | Pre-commit + CI |
| Contenedores | Trivy | Analiza todo |
| IaC | Checkov | Completo, gratuito |
| SBOM | Syft + Grype | Generar + analizar |
| DAST | ZAP Baseline | Estándar, fiable |
Coste total: 0€. Tiempo de configuración: 3-4 horas.
Lecturas adicionales
- Documentación de Semgrep
- Snyk Learn — Formación gratuita en seguridad
- OWASP DevSecOps Guideline
- Funciones de seguridad de GitHub
- Análisis de seguridad de GitLab
- Documentación de Trivy
- Documentación de Checkov
- OWASP Testing Guide
Qué sigue
Ha integrado el análisis de seguridad en su pipeline de CI/CD. Próximo capítulo: seguridad de contenedores e infraestructura cloud — proteger imágenes Docker, configuraciones cloud e infraestructura como código.