FlowSentry
Escáner de seguridad para exportaciones de flujos de trabajo de n8n: 18 reglas de análisis estático mapeadas a OWASP Agentic AI (autenticación de webhook, secretos codificados, SSRF/IMDS, inyección SQL, sumideros de exfiltración). Servidor MCP gratuito + API x402 de pago (0,50 USDC/escaneo, liquidación en Base).
Documentación
FlowSentry
Escáner de seguridad para flujos de trabajo de n8n: 18 reglas, cero dependencias, listo para CI.
FlowSentry analiza tus exportaciones JSON de flujos de trabajo de n8n y señala las fallas que seguimos viendo en el mundo real: webhooks sin autenticación, secretos codificados, SSRF hacia metadatos de la nube, inyección de shell a través de Execute Command, nodos de código estilo eval, SQL construido a partir de entrada del usuario, credenciales con alcance excesivo y más. Salida: terminal, JSON, SARIF 2.1.0 (GitHub Code Scanning) y un informe HTML autocontenido.
- Cero dependencias en tiempo de ejecución (solo stdlib de Python puro, Python 3.9+)
- 18 reglas mapeadas al OWASP Agentic Top 10 (2026)
- Salida SARIF → súbela directamente a GitHub Code Scanning
- Código de salida 1 ante hallazgos → intégralo en CI como puerta de calidad
$ pip install flowsentry
$ flowsentry scan workflows/ --sarif flowsentry.sarif
PyPI: https://pypi.org/project/flowsentry/ · o instala directamente desde GitHub:
pip install git+https://github.com/vasilicasijarvis/flowsentry.git
Sin instalación en absoluto:
git clone https://github.com/vasilicasijarvis/flowsentry
cd flowsentry
python3 flowsentry_cli.py scan ./workflows
Por qué
Los webhooks de n8n están sin autenticación por defecto. La mayoría de las instancias autoalojadas están detrás de un único proxy inverso, y una sola exportación de flujo de trabajo es suficiente para filtrar una clave de API codificada o un nodo Execute Command que interpola datos de solicitud directamente en un shell.
Escaneamos 10 archivos reales y públicos de flujos de trabajo de n8n desde GitHub con FlowSentry v0.1:
| Archivo (repositorio fuente) | Crítico | Medio | Hallazgo notable |
|---|---|---|---|
AI_Bot.json (AnaamRasool/WhatsApp-Bot) | 1 | 4 | Webhook de WhatsApp con authentication: none, las respuestas hacen eco de la salida completa del nodo |
00485-library-install.json (DragonJAR/n8n-workflows-esp) | 2 | 1 | Script Bash que interpola {{$json.library}} en el shell |
n8n/w1.json (Finfra/dockers) | 1 | 2 | Webhook authentication: 'none' |
workflows/103.json (n8n-io/test-workflows) | 4 | 2 | echo 'test' > /tmp/{{$node["Set"].json["filename"]}} |
subagente-citas.json (santifer/jacobo-workflows) | 1 | 9 | Webhook público de reserva de citas, sin autenticación |
nl2sql.json (Wilsonoonn/n8n_nl2sql) | 1 | 9 | Lenguaje natural a SQL detrás de un webhook sin autenticación |
api-authentication.json (yorrickjansen/n8n-webhook-security) | 1 | 5 | Los propios webhooks de demostración aceptan solicitudes sin autenticación |
AIDA Preisalarm, nl2sql auxiliar, openwebui-pipe (3 archivos más) | 0 | 7 | Nodos de código, manejo de errores faltante, modos de respuesta |
Totales: 11 críticos, 39 medios en 10 archivos. El 100% de los archivos tenía al menos un hallazgo.
Estas son exportaciones públicas de flujos de trabajo compartidas por sus autores con fines de aprendizaje/demostración: no se explotó nada y no se accedió a ninguna instancia. FlowSentry es una herramienta defensiva: lee archivos JSON, no envía solicitudes.
Hallazgos reales, textualmente
1. Inyección de shell mediante Execute Command (flujo de trabajo oficial de prueba de n8n):
[!] CRITICAL FS005 Execute Command node without guardrails
node: Execute Command (n8n-nodes-base.executeCommand)
[!] CRITICAL FS009 Expression-based command injection
node: Execute Command
evidence: echo 'test' > /tmp/{{$node["Set"].json["filename"]}}
fix: Never interpolate data into commands; use argv-style APIs or strict
allowlist validation of the entire command string.
2. Webhooks sin autenticación (5 de 10 archivos):
[!] CRITICAL FS001 Webhook endpoint without authentication
node: HTTP Trigger (n8n-nodes-base.webhook)
Webhook node has authentication set to 'none'. Anyone who can reach the
n8n instance can trigger this workflow and its downstream actions.
fix: Set Webhook > Authentication to Basic/Header/JWT auth, or validate a
shared-secret header in the workflow before doing anything sensitive.
3. Lo que detectan las demás reglas (ejemplo elaborado del conjunto de pruebas):
[!] CRITICAL FS002 Hardcoded secret in node parameters
Parameter 'accessToken' looks like it contains a hardcoded secret
(literal value, no expression). Exports of workflows leak like this.
fix: Move the value into an n8n credential and reference it via expressions.
Las reglas FS002–FS004, FS011–FS013 y FS015–FS018 (secretos, SSRF/IMDS, inyección SQL, http simple, nodos de comunidad, sumideros de exfiltración) no se activaron en esta muestra en particular, pero están completamente cubiertas por el conjunto de 40 pruebas en tests/test_rules.py.
Ejecución real, 2026-09-06 — flowsentry scan examples/real en las 10 exportaciones públicas de flujos de trabajo (código de salida 1 como se esperaba ante hallazgos críticos):
examples/real/AI_Bot.json (WhatsApp bot) - 5 finding(s)
[!] CRITICAL FS001 Webhook endpoint without authentication
node: HTTP Trigger (n8n-nodes-base.webhook)
[~] MEDIUM FS017 Webhook response mode exposes internals
node: API: JWT auth with auth server validation (n8n-nodes-base.webhook)
Webhook responseMode='responseNode' - the last node's full output (possibly
including credentials, internal IDs, stack traces) is returned to the
unauthenticated caller.
fix: Return an explicit minimal payload via the Respond to Webhook node.
Summary
critical: 11 high: 0 medium: 39 low: 0
Result: FAIL - fix critical/high findings before production.
Resultados completos legibles por máquina: examples/scan_report.json,
examples/scan_report.sarif y
examples/scan_report.html.
Reglas (v0.1)
| Regla | Severidad | Detecta |
|---|---|---|
| FS001 | crítico | Endpoint de webhook sin autenticación |
| FS002 | crítico | Secreto codificado en parámetros de nodo |
| FS003 | alto | Secreto codificado en cabecera/consulta HTTP |
| FS004 | crítico | SSRF / acceso a endpoint de metadatos de la nube (IMDS 169.254.169.254, GCP, Alibaba) |
| FS005 | crítico | Nodo Execute Command sin salvaguardas |
| FS006 | medio | Nodo de código sin endurecimiento de sandbox (sin ejecutores de tareas) |
| FS007 | crítico | Construcción dinámica de código (eval, new Function, child_process, os, subprocess, $() dinámico) |
| FS008 | medio | Alcance excesivo de credenciales (nombres admin/root/owner, tipos inusuales) |
| FS009 | crítico | Inyección de comandos basada en expresiones ({{$json...}} en shell) |
| FS010 | medio | Manejo de errores faltante (sin errorWorkflow, sin Error Trigger) |
| FS011 | alto | SQL crudo construido a partir de expresiones |
| FS012 | alto | Nodo HTTP sobre http:// simple |
| FS013 | medio | Disparador expuesto (Form/Telegram/IMAP que acepta entrada sin autenticación) |
| FS014 | medio | Reutilización de credenciales en 5+ nodos |
| FS015 | medio | Paquetes de nodos comunitarios/desconocidos |
| FS016 | medio | Datos enviados a sumideros estilo exfiltración (webhook.site, pastebin, ngrok…) |
| FS017 | medio | Modo de respuesta de webhook que hace eco de datos internos |
| FS018 | medio | Nodo Set que almacena secretos en texto plano |
Uso
# Scan files or directories (directories are walked for *.json)
flowsentry scan ./workflows
flowsentry scan export1.json export2.json
# Machine-readable outputs
flowsentry scan ./workflows --json report.json --sarif report.sarif --html report.html
# CI gate: exit 1 when findings at/above severity exist (default: high)
flowsentry scan ./workflows --fail-on critical
flowsentry scan ./workflows --fail-on never # always exit 0
# List rules
flowsentry rules
GitHub Actions
name: flowsentry
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: "3.12" }
- run: pip install git+https://github.com/vasilicasijarvis/flowsentry.git
- run: flowsentry scan ./workflows --sarif flowsentry.sarif --fail-on high
- uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: flowsentry.sarif
Escanear un paquete de exportación de n8n
# From your n8n UI: Workflows > Export (or via n8n CLI)
n8n export:workflow --all --output=./workflows
flowsentry scan ./workflows --html report.html
Demostración

Desarrollo
git clone https://github.com/vasilicasijarvis/flowsentry
cd flowsentry
python3 tests/run_tests.py # 40 tests, zero dependencies
Vuelve a obtener los flujos de trabajo públicos de ejemplo utilizados en el escaneo del README:
python3 scripts/fetch_workflows.py
flowsentry scan examples/real --json examples/scan_report.json
Hoja de ruta
- v0.2 — escaneo en vivo mediante la API REST de n8n, detección de desviaciones (flujo de trabajo cambiado desde el último escaneo)
- v1.0 — FlowSentry Cloud: monitoreo continuo, alertas, panel de múltiples instancias
- v1.5 — auditoría de configuración del servidor MCP (envenenamiento de herramientas, brechas de autenticación, versiones no fijadas)
- v2.0 — paquetes de evidencia de cumplimiento (OWASP Agentic Top 10, EU AI Act, SOC 2)
La versión alojada y continua está en desarrollo: únete a la lista temprana: flowsentry.vercel.app
Licencia
Apache-2.0. Escanea tus propios flujos de trabajo o exportaciones que tengas permiso de analizar.