Dominio 5b: Análisis de código, componentes y build seguro
Dominio 5b: Análisis de código, componentes y build seguro
Esta es la segunda mitad del Dominio 5 — Secure Software Implementation (14% del examen). Si el capítulo 7 trató de escribir código seguro, este trata de verificarlo, componerlo y construirlo de forma segura. Cubre tres subdominios:
- 5.2 Analizar código en busca de riesgos de seguridad (revisión manual y SAST).
- 5.5 Evaluar e integrar componentes (terceros, open source, SCA, licencias).
- 5.6 Aplicar seguridad durante el proceso de build (CI/CD, firmas, integridad del toolchain).
flowchart LR
A[5.2 Analizar<br/>código] --> P[Software seguro<br/>construido]
B[5.5 Evaluar e integrar<br/>componentes] --> P
C[5.6 Seguridad en<br/>el build] --> P
P --> T[Testing<br/>Cap. 9]
💡 Tip de examen: el software moderno es en un 80–90% código de terceros. ISC2 espera que trates el pipeline y las dependencias como parte de tu superficie de ataque, no como algo externo. La seguridad “se corre a la izquierda” (shift left) integrándose en el desarrollo, no atornillándose al final.
0. El contexto: DevSecOps y shift-left
Antes de entrar en las técnicas conviene fijar el marco cultural que ISC2 asume. DevSecOps integra la seguridad como responsabilidad compartida y automatizada dentro del flujo de DevOps, en lugar de dejarla como una compuerta manual al final del proyecto. Dos ideas lo resumen:
- Shift left: mover las actividades de seguridad lo más temprano posible (IDE, commit, PR), donde corregir un defecto es órdenes de magnitud más barato que en producción.
- Automatización: la seguridad debe ejecutarse en cada cambio sin depender de que alguien “se acuerde”; por eso vive en el pipeline como código.
flowchart LR
A[Plan] --> B[Code]
B --> C[Build]
C --> D[Test]
D --> E[Release]
E --> F[Deploy]
F --> G[Operate]
G --> H[Monitor]
H --> A
B -.SAST/secret scan.-> B
C -.SCA.-> C
D -.DAST/IAST.-> D
La consecuencia práctica para este dominio: el análisis de código, el control de componentes y el build seguro no son fases separadas, sino controles continuos incrustados en el ciclo. El resto del capítulo desarrolla cada uno.
1. Análisis de código: revisión manual y SAST (5.2)
El subdominio 5.2 busca encontrar debilidades en el código propio. Hay dos enfoques complementarios: la revisión humana y el análisis automatizado.
1.1 Revisión manual de código (peer review con foco en seguridad)
La revisión de código por pares es la inspección humana del código fuente. Cuando tiene foco en seguridad, el revisor no solo mira estilo y corrección funcional, sino que busca activamente debilidades: validación ausente, manejo de errores inseguro, secretos hardcodeados, uso incorrecto de criptografía, decisiones de autorización dudosas.
Fortalezas y límites:
- Encuentra fallos de lógica de negocio y de autorización que ninguna herramienta detecta (una herramienta no sabe que “solo el dueño puede borrar el recurso”).
- Es costosa en tiempo y depende de la experiencia del revisor.
- Se apoya en checklists (OWASP Code Review Guide, CERT) y en threat modeling para saber dónde mirar.
1.2 Análisis estático (SAST)
SAST (Static Application Security Testing) analiza el código fuente, bytecode o binario sin ejecutarlo. Recorre flujos de datos y control para detectar patrones de debilidad (inyecciones por concatenación, buffer overflows, uso de funciones inseguras, secretos).
- Es una técnica de white-box (tiene acceso total al código).
- Se integra temprano y de forma continua: en el IDE, en pre-commit y en el pipeline.
- Alta cobertura de código pero propenso a falsos positivos (marca lo que parece un patrón pero no es explotable) y a falsos negativos en lógica de negocio.
1.3 ¿Cuándo cada uno?
No compiten; se combinan. SAST cubre amplitud (todo el código, patrones conocidos) de forma barata y repetible; la revisión manual cubre profundidad (lógica, contexto, autorización) donde la herramienta es ciega.
flowchart LR
A[Código] --> B[SAST<br/>amplio, automático,<br/>patrones]
A --> C[Revisión manual<br/>profundo, lógica,<br/>autorización]
B --> D[Triage de<br/>hallazgos]
C --> D
💡 Tip de examen: si el escenario menciona un fallo de lógica de negocio o de autorización que las herramientas no ven, la respuesta es manual/peer code review. Si busca análisis temprano, escalable y automatizado sin ejecutar la app, es SAST. SAST = white-box, sin ejecución; su punto débil son los falsos positivos.
2. Evaluar e integrar componentes de terceros (5.5)
2.1 El problema systems-of-systems
Las aplicaciones actuales son systems-of-systems: se ensamblan a partir de librerías open source, SDKs, servicios y APIs. Cada componente arrastra su propia superficie de ataque y sus vulnerabilidades heredadas (inherited vulnerabilities). Un CVE en una dependencia transitiva —una dependencia de tu dependencia— es tu problema aunque nunca hayas escrito esa línea (esto mapea a OWASP A06: Vulnerable and Outdated Components).
2.2 Software Composition Analysis (SCA)
SCA (Software Composition Analysis) identifica todos los componentes de terceros y open source de la aplicación y los coteja contra bases de datos de vulnerabilidades (NVD/CVE, GitHub Advisories). Es la herramienta específica para el riesgo de dependencias.
SCA responde tres preguntas:
- ¿Qué componentes uso? (incluye transitivos) — genera el inventario / SBOM.
- ¿Tienen vulnerabilidades conocidas? — mapea a CVEs con su severidad.
- ¿Bajo qué licencias? — detecta riesgos legales de licenciamiento.
2.3 Riesgo de licencias
Más allá de la seguridad, cada componente tiene una licencia con obligaciones legales. Las licencias copyleft fuertes (GPL, AGPL) pueden obligar a liberar tu propio código si distribuyes el producto; las permisivas (MIT, Apache 2.0, BSD) imponen mínimas obligaciones. Integrar un componente sin revisar su licencia es un riesgo de negocio real.
| Tipo de licencia | Ejemplos | Riesgo |
|---|---|---|
| Permisiva | MIT, Apache 2.0, BSD | Bajo (atribución) |
| Copyleft débil | LGPL, MPL | Medio (cambios al componente) |
| Copyleft fuerte | GPL, AGPL | Alto (efecto viral sobre tu código) |
2.4 Criterios de evaluación antes de integrar
- Estado de mantenimiento (¿commits recientes?, ¿comunidad activa?, ¿abandonado?).
- Historial de vulnerabilidades y velocidad de parcheo.
- Reputación y procedencia (provenance) del proyecto.
- Compatibilidad de licencia.
- Principio de minimalismo: cada dependencia añadida es superficie de ataque; elimina las que no uses.
💡 Tip de examen: SCA es a los componentes de terceros lo que SAST es al código propio. Si la pregunta trata de CVEs en librerías, dependencias transitivas o licencias open source, la respuesta es SCA / Software Composition Analysis, no SAST. Y el inventario que produce es el SBOM (ver Dominio 8).
3. Gestión de secretos
Los secretos (contraseñas, API keys, tokens, certificados, cadenas de conexión, llaves criptográficas) son un objetivo de altísimo valor. La regla absoluta: jamás hardcodear secretos en el código fuente (mapea a CWE-798, Use of Hard-coded Credentials).
3.1 Por qué no hardcodear
- El secreto queda para siempre en el historial de Git, aunque lo borres después (hay que rotarlo).
- Se filtra al copiar el repo, en forks, en backups y en logs de build.
- No se puede rotar sin desplegar código nuevo.
3.2 Dónde deben vivir los secretos
- Secret vaults / gestores de secretos: HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager. Ofrecen almacenamiento cifrado, control de acceso, rotación automática y auditoría.
- Variables de entorno inyectadas en tiempo de ejecución (mejor que hardcodear, pero cuidado con volcados y logs).
- HSM para llaves criptográficas de alto valor.
3.3 Detección: secret scanning y pre-commit hooks
- Pre-commit hooks: ejecutan un secret scanner antes de permitir el commit, bloqueando la fuga en el origen (herramientas como git-secrets, gitleaks, detect-secrets).
- Secret scanning en el pipeline: escanea todo el repo e historial buscando patrones de credenciales.
- Si un secreto llegó a filtrarse, la respuesta correcta es rotarlo (invalidarlo y emitir uno nuevo), no solo borrar el commit.
💡 Tip de examen: un secreto que estuvo en el repo se considera comprometido aunque lo elimines: la acción correcta es rotarlo. La prevención en capas es pre-commit secret scanning + vault + no hardcodear. Reconoce CWE-798 como “credenciales hardcodeadas”.
4. Versionado, branch protection y control del repositorio
El sistema de control de versiones es la fuente de verdad del código y por tanto un objetivo. Su protección incluye:
- Branch protection sobre ramas críticas (
main, release): prohibir push directo, exigir pull request con revisión aprobada y checks verdes antes del merge. - Commit / tag signing: firmar commits y tags (GPG, SSH, Sigstore) para garantizar la autoría e integridad de las contribuciones.
- Control de acceso por least privilege y MFA obligatorio en las cuentas de desarrolladores.
- Proteger la configuración CI y los secretos del repo frente a cambios no autorizados (un PR malicioso que edita el workflow puede exfiltrar secretos).
💡 Tip de examen: exigir pull request + revisión + checks antes de merge a
maines un control de integridad e separación de funciones en el código. Enlaza con OWASP A08 (Software and Data Integrity Failures).
5. Seguridad durante el proceso de build (5.6)
El build transforma el código y las dependencias en artefactos desplegables. Si el pipeline se compromete, se puede inyectar código malicioso en un binario firmado y “confiable” sin tocar el repositorio: es el patrón de los ataques a la cadena de suministro (SolarWinds, Codecov).
5.1 Un pipeline CI/CD con gates de seguridad
La seguridad se automatiza como gates (quality gates) en el pipeline: etapas que detienen la promoción del artefacto si no se cumplen los criterios de seguridad.
flowchart LR
A[Commit] --> B[Pre-commit:<br/>secret scan]
B --> C[Build]
C --> D[SAST<br/>gate]
D --> E[SCA / dependencias<br/>gate]
E --> F[Secret scanning<br/>del repo]
F --> G[Tests + DAST<br/>en staging]
G --> H[Firma del<br/>artefacto]
H --> I[(Registro de<br/>artefactos)]
I --> J[Deploy]
D -.falla.-> X[Detener pipeline]
E -.falla.-> X
F -.falla.-> X
5.2 Firma de artefactos y code signing
- Code signing: firmar el artefacto con una llave privada; el consumidor verifica con la pública que procede de quien dice (autenticidad) y no fue alterado (integridad). Las llaves de firma deben custodiarse en HSM.
- Las firmas dan no repudio y son la base de la confianza en la distribución de software.
- Ejemplos de tecnología: Sigstore/cosign para artefactos y contenedores, firma de paquetes de sistema.
5.3 Anti-tampering e integridad del toolchain
- Integridad del toolchain: compiladores, linkers y herramientas de build deben provenir de fuentes verificadas y estar libres de manipulación. Un compilador comprometido inyecta backdoors indetectables en el código fuente (“trusting trust”).
- Anti-tampering: verificación de integridad (hashes/firmas) de las dependencias descargadas y de las herramientas, además de checksums en el artefacto final.
5.4 Reproducible builds
Una build reproducible garantiza que, a partir del mismo código fuente, cualquiera obtiene un artefacto bit a bit idéntico. Esto permite verificar de forma independiente que el binario publicado corresponde exactamente al código auditado, cerrando la puerta a manipulaciones introducidas en el build.
5.5 Secure compiler flags y obfuscación
- Secure compiler flags: activar las protecciones que el compilador ofrece: stack canaries (
-fstack-protector),RELRO,PIE/ASLR,FORTIFY_SOURCE,NX/DEP, tratar warnings como errores. Elevan el costo de explotar bugs de memoria. - Obfuscación: dificulta la ingeniería inversa del binario. Es una capa de defense in depth (útil frente a robo de propiedad intelectual o para apps cliente distribuidas), no un control de seguridad primario: no corrige debilidades, solo ralentiza al atacante. Es “security through obscurity” y no debe sustituir controles reales.
💡 Tip de examen: varias trampas frecuentes: (1) firmar un artefacto no lo hace seguro, solo prueba autenticidad e integridad —un artefacto vulnerable firmado sigue siendo vulnerable; (2) la obfuscación no es un control primario (security through obscurity); (3) proteger el pipeline y el toolchain es parte de la seguridad del build porque un CI comprometido inyecta código en artefactos “confiables”.
5.6 Escaneo de contenedores e infraestructura como código
El artefacto moderno rara vez es un binario suelto: suele ser una imagen de contenedor definida por infraestructura como código. La seguridad del build extiende sus gates a estas capas:
- Container image scanning: analiza las imágenes en busca de paquetes del sistema operativo vulnerables, secretos incrustados y configuraciones inseguras (correr como
root, capabilities excesivas). Se ejecuta en el pipeline antes de publicar la imagen al registro. - IaC scanning: analiza plantillas Terraform, CloudFormation, manifiestos Kubernetes o Dockerfiles buscando misconfiguraciones (buckets públicos, puertos abiertos, cifrado desactivado) antes de aplicarlas. Es shift-left aplicado a la infraestructura.
- Policy as code: expresar las reglas de cumplimiento como código evaluable (p. ej. con motores de políticas) para que el pipeline rechace automáticamente lo que viole la política de seguridad.
5.7 Provenance, attestation y SLSA
Para dar confianza verificable en cómo se produjo un artefacto han surgido marcos de integridad de la cadena de suministro:
- Provenance: metadatos verificables sobre el origen de un artefacto: de qué código fuente, con qué builder y con qué entradas se construyó.
- Attestation: declaración firmada que vincula el artefacto con su provenance y con los controles que pasó (p. ej. “este binario pasó SAST y SCA”).
- SLSA (Supply-chain Levels for Software Artifacts): marco escalonado (niveles progresivos) que define requisitos crecientes de integridad del build y de provenance para resistir manipulaciones de la cadena de suministro.
Estos conceptos conectan directamente con el Dominio 8 (cadena de suministro) y con el SBOM: el SCA produce el inventario, y la provenance/attestation prueban que ese inventario y ese artefacto son auténticos.
flowchart LR
A[Código fuente] --> B[Builder de confianza]
B --> C[Artefacto]
B --> D[Provenance firmada]
C --> E[Attestation]
D --> E
E --> F{Verificación en<br/>el deploy}
F -->|Válida| G[Desplegar]
F -->|Inválida| H[Rechazar]
5.8 Ejemplos de ataques a la cadena de suministro del build
Entender por qué importa el build seguro se ilustra con incidentes reales, cuyo patrón ISC2 espera que reconozcas:
| Ataque | Vector | Lección |
|---|---|---|
| SolarWinds | Malware inyectado en el proceso de build, distribuido en actualizaciones firmadas | Un build comprometido produce artefactos “confiables” maliciosos |
| Codecov | Script de CI alterado exfiltró secretos de entornos de build | Proteger el toolchain y los secretos del pipeline |
| Dependency confusion | Publicar un paquete público con el nombre de uno interno | Fijar fuentes de paquetes; namespaces privados |
| Typosquatting | Paquete malicioso con nombre parecido a uno popular | Verificar nombres y procedencia antes de integrar |
💡 Tip de examen: los ataques a la cadena de suministro explotan la confianza transitiva (confías en tu proveedor, que confía en el suyo). Las defensas del build son provenance/attestation, firma, integridad del toolchain, fijación de fuentes de paquetes y SBOM. Reconoce dependency confusion y typosquatting como riesgos de la fase de componentes/build.
6. Comparación: SAST vs SCA vs revisión manual
Las tres técnicas del análisis de implementación se complementan; ninguna sustituye a las otras. Esta tabla es de alto valor para el examen:
| Aspecto | SAST | SCA | Revisión manual |
|---|---|---|---|
| Qué analiza | Código propio (fuente/bytecode) | Componentes de terceros y open source | Código propio (humano) |
| Qué encuentra | Debilidades de patrón: inyección, memoria, secretos | CVEs conocidos en dependencias, licencias | Lógica de negocio, autorización, contexto |
| Ejecuta la app | No (estático) | No (analiza el manifiesto/binarios) | No |
| Automatización | Alta | Alta | Baja (humana) |
| Falsos positivos | Altos | Bajos–medios | Bajos (juicio humano) |
| Falsos negativos | Lógica de negocio | Vulns no publicadas / zero-day | Depende de la pericia |
| Momento del SDLC | Temprano y continuo (IDE, commit, CI) | Continuo (al añadir/actualizar deps) | En pull request / hitos |
| Coste | Bajo por corrida | Bajo | Alto (tiempo experto) |
flowchart TD
subgraph Análisis de implementación
S[SAST<br/>mi código, patrones]
C[SCA<br/>dependencias, CVEs]
M[Revisión manual<br/>lógica y autorización]
end
S --> R[Cobertura combinada<br/>amplitud + composición + profundidad]
C --> R
M --> R
💡 Tip de examen: memoriza la división de trabajo: SAST = mi código / patrones, SCA = código ajeno / CVEs y licencias, revisión manual = lógica y autorización. Cuando una pregunta describa la debilidad, identifica quién la encuentra. Un programa maduro usa las tres, integradas en el pipeline como gates.
Puntos clave
- El Dominio 5b cubre 5.2 (análisis de código), 5.5 (componentes) y 5.6 (build seguro); complementa la codificación del capítulo 7 verificando, componiendo y construyendo de forma segura.
- SAST analiza el código propio sin ejecutarlo (white-box), es escalable pero genera falsos positivos; la revisión manual encuentra fallos de lógica y autorización que las herramientas no ven. Se combinan.
- El software es mayormente de terceros: SCA inventaría dependencias (incluidas transitivas), detecta CVEs heredados (OWASP A06) y riesgos de licencia. SCA es a los componentes lo que SAST al código propio.
- Evalúa cada componente por mantenimiento, historial de vulnerabilidades, procedencia y licencia; minimiza dependencias porque cada una es superficie de ataque.
- Nunca hardcodees secretos (CWE-798); guárdalos en vaults con rotación, detéctalos con pre-commit + secret scanning, y rota cualquier secreto que se haya filtrado.
- Protege el repositorio con branch protection, PR con revisión, commit signing y MFA (integridad, OWASP A08).
- Asegura el build con gates automáticos (SAST, SCA, secret scan, tests) que detienen la promoción, y protege el pipeline y el toolchain frente a manipulación.
- Firmar un artefacto prueba autenticidad e integridad, no ausencia de vulnerabilidades; usa HSM para las llaves de firma.
- Reproducible builds, secure compiler flags y anti-tampering verifican que el artefacto publicado corresponde al código auditado; la obfuscación es defensa en profundidad, no un control primario.
- Retén la tabla SAST vs SCA vs revisión manual: qué encuentra cada uno, sus falsos positivos y su momento en el SDLC.