← CC3091

DevSecOps

Semestre 02, 2026

Introducción

Problema

La revisión manual de seguridad al final del ciclo no escala a un ritmo de varios despliegues por día.

  • Con integración y despliegue continuos, el tiempo entre un commit y producción se reduce de meses a horas.
  • Una auditoría manual de dos semanas por versión no puede ejecutarse en cada despliegue.
  • DevSecOps implementa los controles de seguridad como etapas automatizadas del pipeline, ejecutadas en cada commit.

DevSecOps

Definición

Práctica que integra la seguridad como un componente fundamental del modelo DevOps, desde las primeras etapas del desarrollo (NIST).

  • Los requisitos de seguridad se definen junto con los funcionales, y los controles los mantiene el mismo equipo que desarrolla y opera el sistema.
  • Se implementa con herramientas de análisis integradas al repositorio, al pipeline de CI/CD y al entorno de ejecución.

El costo de una brecha

Cifras del informe Cost of a Data Breach 2025 de IBM y el Ponemon Institute.

Costo promedio global: 4.44 millones de dólares por brecha.
Costo promedio en Estados Unidos: 10.22 millones de dólares, el más alto registrado para cualquier región.
Tiempo para identificar y contener una brecha: 241 días, el valor más bajo en nueve años y aun así casi ocho meses.

Importancia de la seguridad

Reputación: la pérdida de clientes es un componente principal del costo.
Regulación: leyes como el GDPR imponen multas y obligaciones de notificación.
Continuidad: un ransomware puede detener la operación completa de una organización.
Privacidad: una brecha expone datos personales de los usuarios.
Daño en cadena: un proveedor comprometido afecta a todos los que dependen de él.
Corrección tardía: en producción requiere respuesta a incidentes y análisis forense.

El modelo tradicional

La revisión de seguridad es una etapa posterior al desarrollo, ejecutada por un equipo separado antes de la liberación.

  • Los hallazgos se reportan semanas después del commit que los introdujo.
  • Corregir un defecto de diseño al final obliga a rehacer trabajo que se había dado por terminado.
  • La capacidad del equipo de seguridad limita el número de liberaciones posibles.
  • Los hallazgos no críticos se difieren y se acumulan como deuda de seguridad.

Shift left

Definición

Mover las actividades de seguridad hacia la izquierda de la línea de tiempo del ciclo de vida, hacia el diseño y la codificación.

  • La guía DevSecOps de OWASP plantea como objetivo detectar los problemas de seguridad lo más rápido posible.
  • Un hallazgo reportado en el pull request lo corrige el autor del cambio antes del merge. En producción requiere un proceso de respuesta a incidentes.

Seguridad en todo el ciclo

Malentendido común

Shift left no significa abandonar la seguridad en producción.

  • Después del despliegue se publican CVE nuevos que afectan a código y dependencias que ya pasaron el pipeline.
  • Los controles en producción, como monitoreo, WAF y escaneo periódico de dependencias, siguen siendo necesarios.

Principios de DevSecOps

Responsabilidad compartida: cada persona responde por la seguridad de lo que construye.
Automatización: los controles corren en cada commit, sin depender de la memoria de nadie.
Retroalimentación temprana: el hallazgo llega a quien escribió el código.
Seguridad como código: políticas, reglas e infraestructura versionadas.
Mínimo privilegio: personas, servicios y pipelines con solo los permisos necesarios.
Monitoreo continuo: el sistema se observa en producción.

El marco SSDF del NIST

El Secure Software Development Framework (SP 800-218) organiza las prácticas de desarrollo seguro en cuatro grupos.

PO, preparar la organización: requisitos, roles, capacitación y herramientas.
PS, proteger el software: código, artefactos y build protegidos contra manipulación.
PW, producir software bien asegurado: modelado de amenazas, revisión y pruebas.
RV, responder a vulnerabilidades: identificar, priorizar y corregir tras la entrega.

Un pipeline con controles de seguridad

flowchart LR
    subgraph P[Planificar]
        P1[Modelado de amenazas]
    end
    subgraph C[Codificar]
        C1[Pre-commit y secretos]
    end
    subgraph B[Build]
        B1[SAST y SCA]
    end
    subgraph T[Pruebas]
        T1[DAST]
    end
    subgraph D[Despliegue]
        D1[IaC, imágenes y firma]
    end
    subgraph O[Operación]
        O1[Monitoreo y respuesta]
    end
    P --> C --> B --> T --> D --> O
        

Seguridad en el ciclo de vida

Planificación: requisitos de seguridad y modelado de amenazas.
Codificación: hooks de pre-commit, detección de secretos y linters.
Build: análisis estático (SAST) y de dependencias (SCA).
Pruebas: análisis dinámico (DAST) contra la aplicación en ejecución.
Despliegue: análisis de IaC e imágenes, firma de artefactos.
Operación: monitoreo, registro de eventos y respuesta a incidentes.

Modelado de amenazas

Definición

Actividad de diseño que analiza qué puede salir mal en un sistema antes de construirlo.

  • Es la única práctica del ciclo que encuentra defectos de diseño, porque ninguna herramienta automática sabe lo que el sistema debería hacer.
  • El modelo STRIDE de Microsoft clasifica las amenazas en seis categorías.

STRIDE

Spoofing: suplantar la identidad de otro usuario o servicio.
Tampering: modificar datos o código sin autorización.
Repudiation: negar una acción porque no quedó registro.
Information disclosure: exponer información a quien no debe verla.
Denial of service: dejar el sistema sin capacidad de atender.
Elevation of privilege: obtener permisos que no corresponden.

Tipos de análisis automatizado

TécnicaQué analizaHerramientas
SecretosCredenciales en el código y el historialGitleaks, TruffleHog
SASTEl código fuente, sin ejecutarloSemgrep, CodeQL
SCALas dependencias de tercerosnpm audit, Dependabot
DASTLa aplicación en ejecuciónOWASP ZAP, Burp
IaCTerraform, Kubernetes, DockerCheckov, tfsec
ContenedoresImágenes y paquetes del sistemaTrivy, Grype

SAST y DAST

Las dos técnicas detectan clases distintas de defectos y se ejecutan en etapas distintas del pipeline.

SAST

Analiza el código fuente sin ejecutarlo. Corre en el build, reporta archivo y línea, y tiene más falsos positivos. No detecta errores de configuración del entorno.

DAST

Envía peticiones maliciosas a la aplicación desplegada en un entorno de pruebas. Detecta errores de configuración y de comportamiento en ejecución, pero no reporta la línea responsable.

Caso Equifax, 2017

Caso

Apache publicó el 7 de marzo un parche para una vulnerabilidad crítica de Apache Struts (CVE-2017-5638). El portal de disputas de Equifax nunca se actualizó, los atacantes entraron desde mediados de mayo y se expusieron datos de cerca de 147 millones de personas.

  • La organización no tenía un inventario que relacionara cada aplicación con las versiones de sus dependencias.
  • Práctica que lo habría evitado. Inventario de dependencias y SCA en cada build.

Caso SolarWinds, 2020

Caso

Los atacantes comprometieron el sistema de build e inyectaron el malware Sunburst en las actualizaciones de Orion. Salieron firmadas por SolarWinds y cerca de 18,000 organizaciones las instalaron.

  • El malware no estaba en el repositorio. Se inyectaba durante la compilación, así que la revisión de código no podía detectarlo.
  • Práctica que lo habría mitigado. Proteger el pipeline como producción, builds reproducibles y registros de procedencia (SLSA).

Caso Codecov, 2021

Caso

Un atacante modificó el script de Bash que miles de pipelines de CI descargaban en cada corrida. Durante dos meses, el script envió a un servidor externo las variables de entorno de esos pipelines, con sus credenciales y tokens.

  • Las variables de entorno del pipeline contenían credenciales de despliegue, tokens de repositorios y claves de servicios en la nube.
  • Práctica que lo habría mitigado. Verificar la integridad de lo descargado, fijar versiones y dar al pipeline solo los secretos mínimos.

Caso Log4Shell, 2021

Caso

Una vulnerabilidad en Log4j, la biblioteca de registro más usada en Java (CVE-2021-44228), permitía ejecutar código remoto con una sola cadena de texto escrita en un log. Recibió la severidad máxima de 10 en CVSS.

  • Log4j aparecía con frecuencia como dependencia transitiva, sin declararse en el archivo de dependencias del proyecto.
  • Práctica que lo habría mitigado. Un SBOM por artefacto y análisis de dependencias transitivas.

Caso xz-utils, 2024

Caso

Un ingeniero notó que SSH tardaba medio segundo más de lo normal y encontró una puerta trasera en xz-utils (CVE-2024-3094). La introdujo un colaborador que pasó cerca de dos años ganándose la confianza del proyecto hasta ser mantenedor.

  • El código malicioso no estaba en el repositorio visible, sino en los archivos de distribución empaquetados.
  • Práctica que lo habría mitigado. Builds reproducibles que verifiquen que el paquete distribuido corresponde al código del repositorio.

Caso Toyota, 2022

Caso

Un contratista publicó por error parte del código de la aplicación T-Connect en un repositorio público de GitHub. Contenía una clave de acceso que estuvo expuesta casi cinco años, con acceso a cerca de 296,000 correos de clientes.

  • Práctica que lo habría evitado. Un hook de pre-commit que detecte secretos y credenciales guardadas en un gestor de secretos, nunca en el código.

Lecciones de los casos

CasoQué fallóPráctica
EquifaxDependencia sin parcharSCA e inventario
SolarWindsBuild comprometidoIntegridad y procedencia
CodecovScript del pipeline alteradoVersiones fijas, mínimo privilegio
Log4ShellBiblioteca sin ubicarSBOM
xz-utilsMantenedor maliciosoVerificación y monitoreo
ToyotaClave en el códigoDetección de secretos

Secretos en el código


// Inseguro, la clave queda en el repositorio
const stripe = new Stripe('sk_live_51Hx9QfK2...');

// Seguro, la clave se lee del entorno
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
Importante

Una clave publicada queda en el historial de Git aunque un commit posterior la borre. Se revoca y se emite una nueva.

Hook de pre-commit

Gitleaks revisa cada commit en la máquina del desarrollador y lo rechaza si encuentra un secreto.


repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.24.2
    hooks:
      - id: gitleaks

Un pipeline DevSecOps

Enunciado

Se requiere un workflow de GitHub Actions que, en cada pull request dirigido al main branch, busque secretos en el historial, revise las dependencias en busca de vulnerabilidades conocidas y ejecute un análisis estático con las reglas de OWASP Top 10. Si cualquier control encuentra un problema, el pull request no se puede fusionar.

Un pipeline DevSecOps


name: Seguridad
on:
  pull_request:
    branches: [main]
permissions:
  contents: read
jobs:
  analizar:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: {{ secrets.GITHUB_TOKEN }}
      - run: npm ci
      - run: npm audit --audit-level=high
      - run: >
          pipx run semgrep scan
          --config p/owasp-top-ten --error

name: Seguridad
on:
  pull_request:
    branches: [main]
permissions:
  contents: read
jobs:
  analizar:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: {{ secrets.GITHUB_TOKEN }}
      - run: npm ci
      - run: npm audit --audit-level=high
      - run: >
          pipx run semgrep scan
          --config p/owasp-top-ten --error
on:
  pull_request:

El workflow corre en cada pull request hacia el main branch. El análisis se ejecuta antes del merge, cuando el cambio todavía no está en la rama principal.


name: Seguridad
on:
  pull_request:
    branches: [main]
permissions:
  contents: read
jobs:
  analizar:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: {{ secrets.GITHUB_TOKEN }}
      - run: npm ci
      - run: npm audit --audit-level=high
      - run: >
          pipx run semgrep scan
          --config p/owasp-top-ten --error
permissions:
  contents: read

Limita el token del pipeline a solo lectura. Si un paso o una acción de terceros se compromete, el token no permite escribir en el repositorio.


name: Seguridad
on:
  pull_request:
    branches: [main]
permissions:
  contents: read
jobs:
  analizar:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: {{ secrets.GITHUB_TOKEN }}
      - run: npm ci
      - run: npm audit --audit-level=high
      - run: >
          pipx run semgrep scan
          --config p/owasp-top-ten --error
fetch-depth: 0

Descarga el historial completo y no solo el último commit. Un secreto borrado en un commit posterior sigue existiendo en los anteriores.


name: Seguridad
on:
  pull_request:
    branches: [main]
permissions:
  contents: read
jobs:
  analizar:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: {{ secrets.GITHUB_TOKEN }}
      - run: npm ci
      - run: npm audit --audit-level=high
      - run: >
          pipx run semgrep scan
          --config p/owasp-top-ten --error
gitleaks/
gitleaks-action@v2

Gitleaks revisa los commits del pull request en busca de claves, tokens y contraseñas. El hook de pre-commit depende de la configuración de cada máquina, y este paso aplica el mismo control en el servidor.


name: Seguridad
on:
  pull_request:
    branches: [main]
permissions:
  contents: read
jobs:
  analizar:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: {{ secrets.GITHUB_TOKEN }}
      - run: npm ci
      - run: npm audit --audit-level=high
      - run: >
          pipx run semgrep scan
          --config p/owasp-top-ten --error
npm ci
npm audit
--audit-level=high

Instala las dependencias exactas del archivo de bloqueo y las compara con la base de vulnerabilidades conocidas. Falla solo con severidad alta o crítica, para no bloquear por cada hallazgo menor.


name: Seguridad
on:
  pull_request:
    branches: [main]
permissions:
  contents: read
jobs:
  analizar:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: {{ secrets.GITHUB_TOKEN }}
      - run: npm ci
      - run: npm audit --audit-level=high
      - run: >
          pipx run semgrep scan
          --config p/owasp-top-ten --error
semgrep scan
--config p/owasp-top-ten
--error

Análisis estático con las reglas de OWASP Top 10. La opción error hace que el paso falle si hay hallazgos. Con una regla de protección del main branch que exige este check, el pull request no se puede fusionar mientras falle.

Gestión de hallazgos

Cada hallazgo se clasifica para decidir si bloquea el merge o solo se registra.

Severidad: CVSS puntúa cada vulnerabilidad de 0 a 10.
Umbral de bloqueo: críticas y altas detienen el pipeline, el resto se registra.
Triage: real, falso positivo o riesgo aceptado, con la decisión documentada.
Plazos: por ejemplo siete días para críticas y treinta para altas.
Excepciones con fecha: un riesgo aceptado vence y tiene responsable.

Cadena de suministro de software

El código de terceros se ejecuta con los mismos permisos que el propio.

SBOM: lista de componentes de un artefacto, en CycloneDX o SPDX.
Actualización automática: Dependabot y Renovate abren pull requests.
Versiones fijadas: archivos de bloqueo y acciones fijadas por versión.
Firma de artefactos: Sigstore permite verificar que no hubo alteración.
SLSA: niveles de protección del proceso que produce el artefacto.

Relación con OWASP Top 10

Categoría OWASPControl en el pipeline
A02 Security MisconfigurationAnálisis de IaC y DAST
A03 Supply Chain FailuresSCA, SBOM y firma de artefactos
A04 Cryptographic FailuresDetección de secretos y SAST
A05 InjectionSAST y DAST
A06 Insecure DesignModelado de amenazas
Límite

Ninguna herramienta detecta un diseño inseguro, porque no sabe lo que el sistema debería hacer.

Antipatrones frecuentes

Seguridad como departamento: los controles los configura y atiende un equipo externo al equipo de desarrollo.
Herramienta antes que proceso: comprar un escáner sin definir quién atiende los hallazgos ni en qué plazo.
Análisis concentrados al final: SAST, SCA y DAST se ejecutan solo antes del despliegue, lejos del commit que introdujo el defecto.

Antipatrones frecuentes

Falsos positivos sin triage: un volumen alto de hallazgos sin clasificar lleva a desactivar o ignorar los controles.
Umbral mal definido: bloquear por cualquier severidad detiene el desarrollo, y no bloquear nunca deja pasar vulnerabilidades críticas.
Confiar solo en herramientas: los escáneres no encuentran defectos de diseño ni errores de lógica de negocio.

Cultura de seguridad

Security champions: una persona por equipo con formación adicional, enlace con el equipo de seguridad.
Postmortems sin culpables: el análisis de un incidente se centra en las causas técnicas y de proceso.
Capacitación continua: el equipo conoce las vulnerabilidades comunes de su stack.
Definición de terminado: una historia no está terminada si el pipeline de seguridad no está en verde.

Métricas de DevSecOps

MétricaQué indica
Tiempo medio de correcciónDe la detección a la corrección, por severidad
Vulnerabilidades abiertasCuántas hay por severidad y su evolución
Vulnerabilidades escapadasLas encontradas en producción y no en el pipeline
Cobertura de análisisPorcentaje de repositorios con controles activos
Tasa de falsos positivosHallazgos que no resultan ser un problema real