Arquitectura del Motor de Analisis¶
Documento tecnico para analistas de seguridad
1. Vision General¶
El motor de analisis de mcp-scan esta disenado como un pipeline modular que procesa codigo fuente de servidores MCP para detectar vulnerabilidades de seguridad. La arquitectura sigue los principios de Clean Architecture con dependencias hacia adentro.
1.1 Diagrama de Alto Nivel¶
+------------------------------------------------------------------+
| CAPA DE ENTRADA |
| +------------+ +------------+ +------------+ +------------+ |
| | CLI Tool | | Go API | | Config | | Baseline | |
| | (Cobra) | | (pkg/scan) | | (YAML) | | Filter | |
| +------------+ +------------+ +------------+ +------------+ |
+------------------------------------------------------------------+
|
v
+------------------------------------------------------------------+
| CAPA DE ORQUESTACION |
| +----------------------------------------------------------+ |
| | Scanner | |
| | - Coordina el pipeline completo | |
| | - Maneja paralelismo (worker pool) | |
| | - Aplica timeouts y cancelacion | |
| +----------------------------------------------------------+ |
+------------------------------------------------------------------+
|
v
+------------------------------------------------------------------+
| CAPA DE ANALISIS |
| +---------------+ +---------------+ +---------------+ |
| | Discovery | | Parser | | Surface | |
| | (glob-based) | | (tree-sitter) | | Extractor | |
| +---------------+ +---------------+ +---------------+ |
| | |
| v |
| +---------------+ +---------------+ +---------------+ |
| | Pattern | | Taint | | ML | |
| | Engine | | Engine | | Classifier | |
| +---------------+ +---------------+ +---------------+ |
| +---------------+ +---------------+ |
| | LLM | | CodeQL | |
| | Detector | | Client | |
| +---------------+ +---------------+ |
+------------------------------------------------------------------+
|
v
+------------------------------------------------------------------+
| CAPA DE SOPORTE |
| +---------------+ +---------------+ +---------------+ |
| | Catalog | | Call Graph | | Type Info | |
| | (src/sink) | | Builder | | System | |
| +---------------+ +---------------+ +---------------+ |
| +---------------+ +---------------+ +---------------+ |
| | Import | | MSSS | | Scoring | |
| | Resolver | | Calculator | | Context | |
| +---------------+ +---------------+ +---------------+ |
+------------------------------------------------------------------+
|
v
+------------------------------------------------------------------+
| CAPA DE SALIDA |
| +---------------+ +---------------+ +---------------+ |
| | JSON | | SARIF | | Evidence | |
| | Reporter | | Reporter | | Bundle | |
| +---------------+ +---------------+ +---------------+ |
+------------------------------------------------------------------+
2. Pipeline de Analisis¶
2.1 Fases del Pipeline¶
El pipeline de analisis consta de las siguientes fases ejecutadas secuencialmente:
FASE 1: Discovery
|
v
FASE 2: Parsing (paralelo)
|
v
FASE 3: Surface Extraction
|
v
FASE 4: Analysis (paralelo)
| +-- Pattern Engine
| +-- Taint Engine
| +-- ML Classifier
| +-- LLM Detector (opcional)
| +-- CodeQL (opcional)
|
v
FASE 5: Normalization
|
v
FASE 6: Scoring
|
v
FASE 7: Reporting
2.2 Detalle de Cada Fase¶
FASE 1: Discovery¶
Ubicacion: internal/discovery/discovery.go
Funcion: Identificar todos los archivos de codigo fuente a analizar.
Proceso: 1. Recorrer directorio con patrones glob (include/exclude) 2. Filtrar por extensiones soportadas (.py, .ts, .tsx, .js, .jsx, .go) 3. Calcular SHA-256 de cada archivo para el manifest 4. Registrar tamano y ruta absoluta
Salida: Lista de FileInfo con path, hash, size, language
FASE 2: Parsing¶
Ubicacion: internal/parser/
Funcion: Convertir codigo fuente en AST normalizado.
Proceso:
1. Distribuir archivos entre workers (paralelo)
2. Para cada archivo:
- Seleccionar parser tree-sitter segun lenguaje
- Parsear a AST nativo
- Convertir a AST normalizado (internal/ast/)
3. Extraer: funciones, clases, imports, decoradores, llamadas
Salida: Lista de *ast.File con estructura normalizada
Lenguajes soportados: | Lenguaje | Extension | Tree-sitter Grammar | Estado | |----------|-----------|---------------------|--------| | Python | .py | tree-sitter-python | Completo | | TypeScript | .ts, .tsx, .mts, .cts | tree-sitter-typescript | Completo | | JavaScript | .js, .jsx, .mjs, .cjs | tree-sitter-javascript | Completo | | Go | .go | tree-sitter-go | Solo parsing |
FASE 3: Surface Extraction¶
Ubicacion: internal/surface/surface.go
Funcion: Identificar la superficie MCP del servidor.
Proceso: 1. Detectar SDK utilizado (mcp, fastmcp, @modelcontextprotocol/sdk) 2. Para cada archivo: - Buscar decoradores de herramientas (@tool, @server.tool) - Extraer nombre, descripcion, schema - Identificar handler asociado 3. Detectar tipo de transporte (stdio, HTTP, WebSocket) 4. Detectar senales de autenticacion (cookies, headers, OAuth)
Salida: *surface.MCPSurface con Tools, Resources, Prompts, Transport, AuthSignals
FASE 4: Analysis¶
Ubicacion: Multiples modulos
Funcion: Detectar vulnerabilidades mediante multiples tecnicas.
Sub-fases paralelas:
| Motor | Ubicacion | Funcion |
|---|---|---|
| Pattern Engine | internal/pattern/ |
Deteccion por regex/AST |
| Taint Engine | internal/taint/ |
Flujo de datos source->sink |
| ML Classifier | internal/ml/ |
Clasificacion de tool poisoning |
| LLM Detector | internal/llm/ |
Analisis semantico (opcional) |
| CodeQL | internal/codeql/ |
Confirmacion secundaria (opcional) |
FASE 5: Normalization¶
Ubicacion: internal/types/types.go
Funcion: Unificar y deduplicar hallazgos.
Proceso: 1. Generar ID unico para cada hallazgo (SHA-256) 2. Deduplicar por ID 3. Aplicar filtro de baseline si existe 4. Ordenar por severidad
Salida: Lista de Finding deduplicada
FASE 6: Scoring¶
Ubicacion: internal/msss/msss.go, internal/scoring/scoring.go
Funcion: Calcular score MSSS y ajustar severidades.
Proceso: 1. Inicializar score base = 100 2. Aplicar penalizaciones por hallazgo 3. Aplicar multiplicador por criticals 4. Ajustar severidad por contexto MCP 5. Determinar nivel de compliance (0-3)
Salida: *msss.Score con total, categorias, nivel
FASE 7: Reporting¶
Ubicacion: internal/reporter/
Funcion: Generar salida en formato solicitado.
Formatos soportados: | Formato | Uso | Contenido | |---------|-----|-----------| | JSON | Procesamiento custom | Hallazgos + manifest + score | | SARIF 2.1.0 | GitHub/GitLab CI | Standard de seguridad | | Evidence | Auditoria | Manifest + trazas + evidencias completas |
3. Componentes Clave¶
3.1 Scanner (Orquestador)¶
Ubicacion: pkg/scanner/scanner.go
El Scanner es el punto de entrada principal y coordina todo el pipeline:
type Scanner struct {
config Config
patternEng *pattern.Engine
taintEng *taint.Engine
surfaceExt *surface.Extractor
mlClassifier ml.Classifier
llmDetector *llm.Detector
codeqlClient *codeql.Client
}
Responsabilidades: - Inicializar todos los motores - Manejar pool de workers para paralelismo - Aplicar timeouts via context - Coordinar fusion de resultados
3.2 Pattern Engine¶
Ubicacion: internal/pattern/engine.go
Motor de deteccion basado en reglas patron:
type Engine struct {
rules []*Rule
severityOverrides map[string]types.Severity
disabledRules map[string]bool
}
Componentes:
- Rules: Lista de reglas con ID, detector, severidad
- Detectors: Implementaciones de interface Detector
- Overrides: Configuracion para ajustar severidades
3.3 Taint Engine¶
Ubicacion: internal/taint/engine.go
Motor de analisis de flujo de datos:
type Engine struct {
catalog *catalog.Catalog
mode Mode // fast o deep
depth int // Profundidad inter-procedural
}
Componentes: - Catalog: Definiciones de sources/sinks/sanitizers - TaintState: Estado de taint por scope - Trace: Registro del camino source->sink
3.4 Catalog¶
Ubicacion: internal/catalog/catalog.go
Catalogo de conocimiento para taint analysis:
Categorias de Sources:
| Categoria | Descripcion |
|-----------|-------------|
| SourceToolInput | Entrada de herramienta MCP |
| SourceEnvVar | Variables de entorno |
| SourceHTTPRequest | Request HTTP |
| SourceFileContent | Contenido de archivo |
| SourceDBResult | Resultado de DB |
Categorias de Sinks:
| Categoria | Clase | Descripcion |
|-----------|-------|-------------|
| SinkExec | A | Ejecucion de comandos |
| SinkEval | A | Evaluacion de codigo |
| SinkFilesystem | B | Operaciones de archivo |
| SinkNetwork | C | Requests de red |
| SinkDatabase | D | Queries SQL |
| SinkLogging | E | Logging de datos |
| SinkResponse | E | Respuestas |
| SinkLLMPrompt | H | Prompts a LLM |
3.5 ML Classifier¶
Ubicacion: internal/ml/classifier.go
Clasificador de machine learning para tool poisoning:
Implementaciones:
- RuleBasedClassifier: Deterministico por reglas
- WeightedClassifier: Pesos entrenados
- EnsembleClassifier: Combinacion de clasificadores
3.6 Surface Extractor¶
Ubicacion: internal/surface/surface.go
Extractor de superficie MCP:
type MCPSurface struct {
Tools []Tool
Resources []Resource
Prompts []Prompt
Transport TransportType
AuthSignals []AuthSignal
}
4. Flujo de Datos Interno¶
4.1 Estructura de Finding¶
Cada hallazgo tiene la siguiente estructura:
type Finding struct {
ID string // SHA-256 hash unico
RuleID string // MCP-X001
Title string // Titulo descriptivo
Severity Severity // critical/high/medium/low/info
Confidence Confidence // high/medium/low
Class VulnClass // A-N
Language Language // python/typescript/javascript/go
Location Location // file, line, column
Evidence Evidence // snippet, trace, LLM analysis
Description string // Descripcion del hallazgo
Remediation string // Como remediar
MCPContext *MCPContext // Tool/handler donde se encontro
Trace *TaintTrace // Traza de taint (si aplica)
}
4.2 Flujo de un Hallazgo¶
Pattern/Taint/ML detecta match
|
v
+-------------------+
| Crear Match |
| - location |
| - snippet |
| - confidence |
+-------------------+
|
v
+-------------------+
| Convertir a |
| Finding |
| - aplicar rule |
| - generar ID |
+-------------------+
|
v
+-------------------+
| Context-Aware |
| Adjustment |
| - MCP tool boost |
| - trace length |
+-------------------+
|
v
+-------------------+
| Normalization |
| - deduplication |
| - baseline filter |
+-------------------+
|
v
+-------------------+
| MSSS Scoring |
| - penalties |
| - multipliers |
+-------------------+
|
v
+-------------------+
| Reporter |
| - JSON/SARIF |
+-------------------+
5. Paralelismo y Rendimiento¶
5.1 Worker Pool¶
El scanner utiliza un pool de workers configurables:
+------------------+
| Scanner |
| +-----------+ |
| | WorkerPool| |
| | (N workers)| |
| +-----------+ |
+------------------+
|
v
+-------+-------+-------+
| | | |
Worker Worker Worker Worker
| | | |
File1 File2 File3 File4
Configuracion:
- --workers N: Numero de workers (0 = auto-detect CPUs)
- Default: numero de CPUs disponibles
5.2 Fases Paralelizables¶
| Fase | Paralela | Notas |
|---|---|---|
| Discovery | No | I/O bound, secuencial |
| Parsing | Si | Por archivo |
| Surface | No | Necesita todos los ASTs |
| Analysis | Si | Por archivo y por motor |
| Normalization | No | Necesita todos los hallazgos |
| Scoring | No | Rapido, no necesario |
| Reporting | No | I/O output |
5.3 Cancelacion y Timeouts¶
El pipeline soporta cancelacion en cualquier fase via context:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
result, err := scanner.Scan(ctx, "/path/to/code")
Cada fase verifica ctx.Done() y termina limpiamente si se cancela.
6. Extensibilidad¶
6.1 Agregar Nuevo Detector¶
-
Implementar interface
Detector: -
Registrar en Pattern Engine:
6.2 Agregar Nuevo Source/Sink¶
- Editar
internal/catalog/catalog.go - Agregar definicion:
6.3 Agregar Nuevo Lenguaje¶
- Agregar grammar tree-sitter en
internal/parser/ - Implementar extractor de AST
- Agregar a
types.Language - Actualizar sources/sinks especificos del lenguaje
7. Archivos Clave¶
| Ruta | Descripcion |
|---|---|
pkg/scanner/scanner.go |
API publica y orquestador |
internal/pattern/engine.go |
Motor de patrones |
internal/taint/engine.go |
Motor de taint |
internal/ml/classifier.go |
Clasificador ML |
internal/ml/features.go |
Extraccion de features |
internal/llm/detector.go |
Detector LLM |
internal/codeql/client.go |
Cliente CodeQL |
internal/surface/surface.go |
Extractor de superficie |
internal/catalog/catalog.go |
Catalogo sources/sinks |
internal/msss/msss.go |
Calculador MSSS |
internal/types/types.go |
Tipos comunes |
8. Flujo de Ejecucion Completo¶
mcp-scan scan /path/to/code --mode fast --output json
|
v
+---------------+
| Load Config | <-- .mcp-scan.yaml o defaults
+---------------+
|
v
+---------------+
| Init Scanner | <-- Crear todos los motores
+---------------+
|
v
+---------------+
| Discovery | <-- Encontrar archivos
+---------------+
|
v
+---------------+
| Parse Files | <-- tree-sitter -> AST
| (parallel) |
+---------------+
|
v
+---------------+
| Extract | <-- Tools, Resources, Transport
| Surface |
+---------------+
|
v
+----------------+----------------+
| | |
v v v
+--------+ +---------+ +------+
|Pattern | | Taint | | ML |
|Engine | | Engine | | Clf |
+--------+ +---------+ +------+
| | |
+----------------+----------------+
|
v
+---------------+
| Merge & Dedup | <-- Unificar hallazgos
+---------------+
|
v
+---------------+
| Apply | <-- Filtrar hallazgos en baseline
| Baseline |
+---------------+
|
v
+---------------+
| Calculate | <-- Score MSSS
| MSSS Score |
+---------------+
|
v
+---------------+
| Generate | <-- JSON output
| Report |
+---------------+
|
v
stdout/file
Siguiente documento: analisis-taint.md