Escanea workloads/ecommerce con rulesets públicos del registro de Semgrep (p/typescript, p/react, p/nextjs, p/security-audit) vía la imagen oficial semgrep/semgrep:1.173.0. Sin --error a propósito: siempre termina en exit 0, solo reporta — primera vuelta para revisar juntos qué reglas deberían pasar a bloquear más adelante. Validado contra el código real: 0 hallazgos en 91 reglas / 72 archivos. Documenta la herramienta en docs/devsecops/sast.md, incluyendo la diferencia con gitleaks/trivy y qué significa (y qué no) un scan limpio.
116 lines
5.3 KiB
Markdown
116 lines
5.3 KiB
Markdown
# SAST (Semgrep) — análisis estático de código
|
|
|
|
!!! info "Qué problema resuelve"
|
|
SAST significa *Static Application Security Testing*: analizar el
|
|
**código fuente** en busca de patrones de programación inseguros, sin
|
|
ejecutar la aplicación. Semgrep lee cada archivo `.ts`/`.tsx` y lo
|
|
compara contra un catálogo de reglas — cada regla describe una forma
|
|
de escribir código que suele terminar en una vulnerabilidad conocida
|
|
(inyección, XSS, uso inseguro de una API, etc.).
|
|
|
|
## En qué se diferencia de Gitleaks y Trivy
|
|
|
|
Las tres herramientas ya integradas a este pipeline analizan cosas
|
|
completamente distintas — vale la pena tenerlo claro porque a primera
|
|
vista "escaneo de seguridad" suena como una sola categoría:
|
|
|
|
| Herramienta | Qué mira | Pregunta que responde |
|
|
|---|---|---|
|
|
| [Gitleaks](gitleaks.md) | El texto de los archivos y el historial de git | "¿Hay una credencial commiteada?" |
|
|
| [Trivy](trivy.md) | Paquetes instalados (imagen) y configuración (YAML) | "¿Alguna dependencia tiene una CVE conocida? ¿El manifiesto de Kubernetes es inseguro?" |
|
|
| **Semgrep (SAST)** | La **lógica** del código que escribimos nosotros | "¿Esta función, tal como está escrita, abre una vulnerabilidad?" |
|
|
|
|
Ninguna de las tres reemplaza a las otras. Una dependencia puede estar
|
|
100% al día (sin CVEs, Trivy contento) y aun así el código propio puede
|
|
construir una URL con un string sin sanitizar y quedar abierto a SSRF —
|
|
eso solo lo detecta un análisis de la lógica del código, que es
|
|
exactamente lo que hace Semgrep.
|
|
|
|
## Qué tipo de bugs detecta (ejemplos genéricos)
|
|
|
|
Los rulesets usados (`p/typescript`, `p/react`, `p/nextjs`,
|
|
`p/security-audit`) cubren, entre otras cosas:
|
|
|
|
- **Inyección**: construir queries, comandos de shell o URLs concatenando
|
|
strings con datos que vienen del usuario, en vez de usar una API
|
|
parametrizada.
|
|
- **XSS en React/Next.js**: usar `dangerouslySetInnerHTML` con contenido
|
|
que no pasó por un sanitizador.
|
|
- **SSRF**: hacer un `fetch()`/request server-side hacia una URL que
|
|
construye el propio usuario, sin validar el host de destino.
|
|
- **Criptografía insegura**: algoritmos de hash débiles (`md5`, `sha1`)
|
|
usados para contraseñas o tokens, en vez de un KDF diseñado para eso.
|
|
- **`eval` / `new Function()`** sobre datos no confiables.
|
|
- **ReDoS**: expresiones regulares con backtracking exponencial que un
|
|
input malicioso puede usar para colgar el proceso.
|
|
- **Prototype pollution**: merges/asignaciones dinámicas de objetos que
|
|
permiten sobrescribir `__proto__`.
|
|
|
|
## Resultado real de esta primera corrida
|
|
|
|
```text
|
|
Scanning 72 files tracked by git with 292 Code rules:
|
|
ts 87 rules 39 files
|
|
js 81 rules 1 file
|
|
json 1 rule 6 files
|
|
|
|
Ran 91 rules on 72 files: 0 findings.
|
|
```
|
|
|
|
`workloads/ecommerce` salió limpio con estos rulesets: **0 hallazgos**.
|
|
|
|
!!! warning "0 hallazgos no significa 'código perfecto'"
|
|
Significa que ningún patrón conocido de estos 91 rules hizo match —
|
|
no es una garantía de ausencia de bugs, solo de ausencia de *estos*
|
|
patrones específicos. SAST tiene falsos negativos por naturaleza (un
|
|
bug de lógica de negocio nuevo, específico de esta app, no está en
|
|
ningún ruleset genérico). El valor de correr esto en cada build no es
|
|
"una vez limpio, siempre limpio" — es que si alguien introduce a
|
|
futuro uno de estos patrones conocidos (por ejemplo, un
|
|
`dangerouslySetInnerHTML` sin sanitizar en un componente nuevo), el
|
|
pipeline lo va a marcar en ese mismo push.
|
|
|
|
## Por qué modo auditoría (no bloquea) en esta primera integración
|
|
|
|
El step corre **sin** la flag `--error` a propósito — Semgrep siempre
|
|
termina con `exit 0`, reporta lo que encuentra pero nunca frena el
|
|
pipeline. Es la primera vez que esta herramienta corre sobre el repo: la
|
|
idea es revisar juntos qué reglas de los 91 activos generan ruido (falsos
|
|
positivos específicos de este código) antes de decidir cuáles deberían
|
|
pasar a bloquear.
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
A[Semgrep scan] --> B{hallazgos?}
|
|
B -- "sí" --> C["se reportan en el log<br/>+ artifact JSON"]
|
|
B -- "no" --> C
|
|
C --> D["✅ pipeline sigue<br/>(exit 0 siempre)"]
|
|
```
|
|
|
|
Una vez que se decida qué reglas son suficientemente confiables para
|
|
esta app, el paso natural es agregar `--error` **con un subconjunto**
|
|
de reglas (no las 91 completas) usando `--config` más específico o
|
|
`.semgrepignore` / reglas individuales marcadas como bloqueantes —
|
|
todavía no se hizo ese recorte.
|
|
|
|
## Los rulesets elegidos
|
|
|
|
- `p/typescript` — patrones generales de TypeScript/JavaScript.
|
|
- `p/react` — específico de componentes React (hooks mal usados, XSS vía
|
|
props/render, etc.).
|
|
- `p/nextjs` — patrones propios del framework (App Router, API routes,
|
|
middlewares).
|
|
- `p/security-audit` — catálogo transversal de seguridad (inyección,
|
|
criptografía débil, deserialización insegura) sin atarse a un
|
|
framework específico.
|
|
|
|
Son rulesets **públicos y gratuitos** del registro de Semgrep — no
|
|
requieren cuenta ni login (`semgrep login` solo hace falta para acceder a
|
|
reglas adicionales de pago, que no se usan acá).
|
|
|
|
## Dónde ver el resultado
|
|
|
|
El JSON completo (`semgrep-report.json`) se publica como artifact del
|
|
pipeline (`semgrep-report`) en cada corrida, tenga o no hallazgos —
|
|
mismo patrón que Gitleaks y Trivy.
|