Modos de Analisis¶
MCP-Scan ofrece dos modos de analisis con diferentes niveles de profundidad y rendimiento.
Tabla de Contenidos¶
- Vision General
- Modo Fast
- Modo Deep
- Comparativa Detallada
- Taint Analysis
- Call Graph
- Cuando Usar Cada Modo
- Optimizacion del Rendimiento
Vision General¶
| Caracteristica | Fast | Deep |
|---|---|---|
| Analisis | Intra-procedural | Inter-procedural |
| Velocidad | Rapido (segundos) | Lento (minutos) |
| Precision | Media | Alta |
| Cobertura | Funcion por funcion | Flujos entre funciones |
| Memoria | Baja | Alta |
| Uso tipico | CI/CD, PRs | Auditorias, certificacion |
Modo Fast¶
Descripcion¶
El modo fast realiza analisis intra-procedural, es decir, analiza cada funcion de forma aislada sin seguir el flujo de datos entre funciones.
Como Funciona¶
# Ejemplo: Funcion con vulnerabilidad
@tool
def execute_command(cmd: str) -> str:
# El modo fast detecta esto porque:
# 1. cmd es parametro de tool (source)
# 2. subprocess.run con shell=True es sink
# 3. El flujo source → sink esta dentro de la misma funcion
return subprocess.run(cmd, shell=True, capture_output=True).stdout
Detecciones en Modo Fast¶
El modo fast detecta:
- Patrones directos - Expresiones regulares sobre codigo
- Flujos intra-procedurales - Source a sink dentro de una funcion
- Configuraciones inseguras - Cookies sin Secure, JWT sin verificacion
- Secretos hardcodeados - Variables con valores sensibles
- Tool poisoning basico - Descripciones maliciosas
# DETECTADO en modo fast
@tool
def run(command: str) -> str:
return os.system(command) # Flujo directo
# NO DETECTADO en modo fast (requiere deep)
@tool
def run(command: str) -> str:
safe_cmd = sanitize(command) # Otra funcion
return execute(safe_cmd) # Otra funcion
Ventajas del Modo Fast¶
- Velocidad: Segundos en lugar de minutos
- Memoria: Bajo consumo de RAM
- Paralelismo: Archivos analizados independientemente
- Determinismo: Resultados consistentes y rapidos
Limitaciones del Modo Fast¶
- No sigue flujos entre funciones
- No detecta sanitizadores en otras funciones
- Puede tener falsos negativos en codigo modular
- No construye call graph
Modo Deep¶
Descripcion¶
El modo deep realiza analisis inter-procedural, construyendo un call graph y siguiendo el flujo de datos a traves de multiples funciones.
Como Funciona¶
# Ejemplo: Flujo entre funciones
def get_user_input() -> str:
return input() # Source
def process_input(data: str) -> str:
return data.strip() # Propagacion
def execute(cmd: str):
os.system(cmd) # Sink
@tool
def handler():
data = get_user_input() # Taint: data
processed = process_input(data) # Taint: processed
execute(processed) # DETECTADO en modo deep
Construccion del Call Graph¶
El modo deep construye un grafo de llamadas:
handler()
├── get_user_input() → [source: user_input]
├── process_input(data) → [taint propagation]
└── execute(cmd) → [sink: os.system]
Detecciones Adicionales en Modo Deep¶
- Flujos inter-procedurales - Source en una funcion, sink en otra
- Sanitizadores en funciones separadas - Reduce falsos positivos
- Callbacks y closures - Variables capturadas
- Imports entre archivos - Flujos cross-file
# DETECTADO en modo deep
# archivo: utils.py
def execute_query(sql: str):
cursor.execute(sql) # Sink
# archivo: handlers.py
@tool
def search(query: str) -> str: # Source
result = execute_query(f"SELECT * WHERE name='{query}'")
return result
Ventajas del Modo Deep¶
- Deteccion de flujos complejos
- Menos falsos negativos
- Analisis de sanitizadores
- Mejor cobertura en codigo modular
Limitaciones del Modo Deep¶
- Mas lento (minutos vs segundos)
- Mayor consumo de memoria
- Puede timeout en proyectos grandes
- No soporta todas las construcciones dinamicas
Comparativa Detallada¶
Tabla de Capacidades¶
| Capacidad | Fast | Deep |
|---|---|---|
| Deteccion de patrones | Si | Si |
| Flujo intra-procedural | Si | Si |
| Flujo inter-procedural | No | Si |
| Call graph | No | Si |
| Analisis de sanitizadores | Parcial | Completo |
| Flujos cross-file | No | Si |
| Closures y callbacks | No | Si |
| Imports/exports | No | Si |
| Resolucion de tipos | Basica | Avanzada |
| Analisis de retornos | No | Si |
Ejemplo Comparativo¶
# Codigo a analizar
def sanitize(data: str) -> str:
return shlex.quote(data)
def execute(cmd: str):
subprocess.run(cmd, shell=True)
@tool
def run_safe(command: str) -> str:
safe = sanitize(command)
execute(safe)
return "done"
@tool
def run_unsafe(command: str) -> str:
execute(command)
return "done"
Resultados:
| Modo | run_safe | run_unsafe |
|---|---|---|
| Fast | ALERTA (falso positivo) | ALERTA (correcto) |
| Deep | OK (sanitizado) | ALERTA (correcto) |
El modo deep reconoce que sanitize() es un sanitizador y no reporta run_safe.
Taint Analysis¶
Que es Taint Analysis¶
Taint analysis rastrea el flujo de datos "contaminados" (tainted) desde fuentes de entrada (sources) hasta operaciones peligrosas (sinks).
Sources (Fuentes de Datos)¶
| Source | Descripcion | Ejemplo |
|---|---|---|
tool_input |
Parametros de tools MCP | @tool def f(cmd: str) |
env_var |
Variables de entorno | os.environ["KEY"] |
http_request |
Datos de request HTTP | request.args |
file_content |
Contenido de archivos | open(f).read() |
db_result |
Resultados de BD | cursor.fetchone() |
config |
Valores de configuracion | config["setting"] |
Sinks (Operaciones Peligrosas)¶
| Sink | Descripcion | Ejemplo |
|---|---|---|
exec |
Ejecucion de comandos | os.system(), subprocess.run() |
eval |
Evaluacion dinamica | eval(), exec() |
filesystem |
Operaciones de archivo | open(), shutil.copy() |
network |
Operaciones de red | requests.get(), urllib.urlopen() |
database |
Queries de BD | cursor.execute() |
logging |
Registro | logger.info() |
response |
Respuestas | return data |
Sanitizers (Funciones Seguras)¶
| Sanitizer | Proposito | Ejemplo |
|---|---|---|
shlex.quote |
Escapar shell | shlex.quote(cmd) |
html.escape |
Escapar HTML | html.escape(text) |
parameterized |
SQL parametrizado | cursor.execute(sql, (param,)) |
os.path.basename |
Solo nombre de archivo | os.path.basename(path) |
Flujo de Taint¶
SOURCE ──► PROPAGACION ──► SANITIZER? ──► SINK
(asignacion, (rompe (operacion
concat, cadena) peligrosa)
llamadas)
Ejemplo de flujo:
@tool
def search(query: str) -> str: # SOURCE: query tainted
sql = f"SELECT * FROM users WHERE name='{query}'" # PROPAGACION: sql tainted
cursor.execute(sql) # SINK: tainted data llega a sink
# ALERTA: SQL Injection
Call Graph¶
Que es el Call Graph¶
Un call graph es un grafo dirigido donde: - Nodos: Funciones/metodos - Aristas: Llamadas entre funciones
Ejemplo de Call Graph¶
def main():
handler()
def handler():
data = get_input()
process(data)
def get_input():
return input()
def process(x):
execute(x)
def execute(cmd):
os.system(cmd)
Call Graph resultante:
Uso del Call Graph¶
El modo deep usa el call graph para:
- Seguir taint entre funciones
- Detectar sanitizadores en el camino
- Calcular alcanzabilidad
- Identificar puntos de entrada
Caching del Call Graph¶
El call graph se puede cachear para escaneos futuros:
# Primer escaneo (construye cache)
mcp-scan scan . --mode deep
# Escaneos siguientes (usa cache)
mcp-scan scan . --mode deep # Mas rapido
El cache se guarda en .mcp-scan/callgraph.gob y se invalida cuando:
- Los archivos cambian (hash diferente)
- Se modifican dependencias
Cuando Usar Cada Modo¶
Usar Modo Fast¶
| Escenario | Razon |
|---|---|
| CI/CD en cada PR | Velocidad critica |
| Pre-commit hooks | Feedback inmediato |
| Desarrollo local | Iteracion rapida |
| Proyectos muy grandes | Evitar timeouts |
| Primera pasada | Identificar obvios |
Usar Modo Deep¶
| Escenario | Razon |
|---|---|
| Auditoria de seguridad | Maxima cobertura |
| Certificacion | Requerido por compliance |
| Release final | Antes de produccion |
| Codigo critico | Alta seguridad requerida |
| Investigacion de hallazgos | Entender flujos |
Estrategia Combinada¶
# En cada PR: fast
mcp-scan scan . --mode fast --fail-on critical
# Nightly: deep
mcp-scan scan . --mode deep --fail-on high
# Pre-release: deep con evidencias
mcp-scan scan . --mode deep --output evidence
Optimizacion del Rendimiento¶
Optimizar Modo Fast¶
# Limitar archivos
include:
- "src/**/*.py" # Solo source
exclude:
- "**/tests/**"
- "**/vendor/**"
# Aumentar workers
scan:
workers: 8
timeout: 2m
Optimizar Modo Deep¶
# Limitar scope
include:
- "src/core/**/*.py" # Solo codigo critico
# Usar cache
scan:
mode: deep
timeout: 30m
workers: 4
# Excluir tests
exclude:
- "**/tests/**"
- "**/mocks/**"
Tips de Rendimiento¶
| Tip | Impacto |
|---|---|
| Excluir node_modules/vendor | Alto |
| Limitar a src/ | Alto |
| Aumentar workers | Medio |
| Usar cache (deep) | Medio |
| Deshabilitar LLM | Medio |
| Deshabilitar CodeQL | Alto |
Benchmarks Tipicos¶
| Proyecto | Archivos | Fast | Deep |
|---|---|---|---|
| Pequeno (10 archivos) | 10 | 2s | 15s |
| Mediano (100 archivos) | 100 | 10s | 2m |
| Grande (1000 archivos) | 1000 | 1m | 15m |
| Muy grande (10000 archivos) | 10000 | 5m | 1h+ |
Resumen¶
| Aspecto | Fast | Deep |
|---|---|---|
| Velocidad | Segundos | Minutos |
| Precision | Media | Alta |
| Memoria | Baja | Alta |
| Call Graph | No | Si |
| Cross-file | No | Si |
| Sanitizadores | Parcial | Completo |
| Uso | CI/CD | Auditorias |
Recomendacion general:
- Desarrollo diario:
--mode fast - Antes de release:
--mode deep - Auditoria formal:
--mode deep --output evidence
Anterior: Configuracion | Siguiente: Formatos de Salida