# 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
+ artifact JSON"] B -- "no" --> C C --> D["✅ pipeline sigue
(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.