Skip to main content

Análisis multi-capa

Nivel Avanzado
Tiempo de lectura ⏱ 15 min
palabras 1234
Temas securitytaint

Análisis multicapa

Objetivo

StaticCodeAudit aplica un análisis multicapa: cada archivo se examina mediante 3 estrategias independientes. Los resultados se cruzan para producir hallazgos de alta confianza, acompañados de una cadena de evidencias verificable.


El problema del análisis monocapa

Un análisis monocapa utiliza un único modo (por ejemplo, una sola búsqueda por patrón) por regla:

Regla sql_injection_fstring
    -> Modo regex: busca ".execute(f""
    -> ¿Coincide? -> Hallazgo (confidence 80, fija)
    -> ¿No coincide? -> Nada

Limitaciones:

  • Si el patrón es demasiado estrecho, se pierde la vulnerabilidad (falso negativo)
  • Si el patrón es demasiado amplio, se detecta ruido (falso positivo)
  • Sin prueba del flujo de datos (usted ve "SQL injection" pero no sabe POR QUÉ)
  • La confidence es fija, no se basa en evidencias reales

La arquitectura multicapa

Para cada archivo, 3 capas se ejecutan en paralelo:

                    +-----------------+
                    | Archivo fuente  |
                    +--------+--------+
                             |
              +--------------+--------------+
              |              |              |
              v              v              v
     +------------+  +------------+  +------------+
     |  Capa 1    |  |  Capa 2    |  |  Capa 3    |
     |  Pattern   |  |  Taint     |  |  Context   |
     |  matching  |  |  analysis  |  |  analysis  |
     +------+-----+  +------+-----+  +------+-----+
            |               |               |
            v               v               v
     +-----------------------------------------+
     |        Fusionador de evidencias         |
     |                                         |
     |  Cruza los resultados de las 3 capas.   |
     |  Calcula la confidence real.            |
     |  Construye la cadena de evidencias.     |
     +----------------+------------------------+
                      |
                      v
              +---------------+
              |   Hallazgo    |
              |  + evidencias |
              |  + confidence |
              +---------------+

Capa 1: Pattern matching

Lo que hace

Busca patrones sintácticos en el código (texto o regex). Capa rápida, con amplia cobertura.

Lo que produce

{
  "layer": "pattern",
  "rule_key": "sql_injection_fstring",
  "file": "src/db.py",
  "line": 42,
  "code": "cursor.execute(f\"SELECT * FROM users WHERE id = {user_id}\")",
  "evidence": "Pattern '.execute(f\"' coincide en la línea 42"
}

Confidence aislada: 65 %

Un pattern match aislado es una señal, no una prueba. El patrón puede coincidir con código seguro (por ejemplo, una cadena de documentación o un comentario).


Capa 2: Taint analysis

Lo que hace

Rastrea el flujo de datos desde una source no confiable (entrada HTTP, CLI, archivo) hasta un sink peligroso (execute, open, system).

Lo que produce

{
  "layer": "taint",
  "rule_key": "taint_sqli",
  "file": "src/db.py",
  "flow": {
    "source": {
      "line": 12,
      "code": "user_id = request.args.get('id')",
      "kind": "http"
    },
    "propagation": [
      {"line": 15, "code": "user_id = int(user_id) if safe else user_id"},
      {"line": 38, "code": "query = f\"SELECT * FROM users WHERE id = {user_id}\""}
    ],
    "sink": {
      "line": 42,
      "code": "cursor.execute(query)",
      "type": "sql_execute"
    },
    "sanitizers_found": false
  },
  "evidence": "Datos HTTP (request.args) propagados sin sanitizer hasta cursor.execute()"
}

Confidence aislada: 85 %

Un taint flow es una prueba sólida: muestra el camino completo. Puede ser un falso positivo si el sanitizer está en una función llamada indirectamente (fuera del archivo).


Capa 3: Context analysis

Lo que hace

Analiza el contexto del archivo para reforzar o refutar los hallazgos de las capas 1 y 2. Responde a preguntas como:

  • ¿El archivo utiliza un ORM (SQLAlchemy, Django ORM)? Si es así, una inyección SQL es menos probable.
  • ¿El archivo importa un framework de sanitización?
  • ¿El archivo es un test, un mock, una fixture? Si es así, ignorar.
  • ¿El archivo gestiona peticiones HTTP (rutas, handlers)?
  • ¿El archivo contiene validaciones de entrada (esquemas, validadores)?

Lo que produce

{
  "layer": "context",
  "file": "src/db.py",
  "signals": {
    "is_test_file": false,
    "has_orm": false,
    "has_raw_sql": true,
    "has_http_handler": true,
    "has_input_validation": false,
    "has_sanitizer": false,
    "framework": "flask"
  },
  "evidence": "Archivo Flask con SQL en bruto, sin ORM, sin validación de entrada"
}

Fusionador de evidencias

Cálculo de la confidence

La confidence final no es un promedio: es un cálculo basado en evidencias independientes.

Confidence = base + bonus_taint + bonus_context - penalizaciones

Casos concretos:

  Pattern aislado, sin contexto:
    65 % (señal débil, puede ser un falso positivo)

  Pattern + contexto que confirma (raw SQL, sin ORM, handler HTTP):
    65 % + 15 % = 80 %

  Pattern + taint flow (source -> sink confirmado):
    65 % + 25 % = 90 %

  Pattern + taint + contexto (triple confirmación):
    65 % + 25 % + 10 % = 95 % (casi seguro)

  Pattern + contexto que REFUTA (ORM presente, archivo de test):
    65 % - 30 % = 35 % (probablemente falso positivo -> eliminado del informe)

Reglas de fusión

1. Si la capa de contexto detecta un archivo de test -> ELIMINAR el hallazgo
    (los archivos de test contienen código vulnerable de forma intencionada)

2. Si la capa taint confirma el flujo -> AUMENTAR la confidence
    y AÑADIR la cadena de evidencias al hallazgo

3. Si la capa de contexto refuta (ORM presente, sanitizer encontrado) ->
    DISMINUIR la confidence. Si < 40 % -> ELIMINAR el hallazgo

4. Si dos reglas diferentes detectan la misma vulnerabilidad en el mismo lugar ->
    FUSIONAR en un único hallazgo con la confidence más alta

5. Si el taint flow atraviesa varios archivos -> AÑADIR la etiqueta
    "cross-file" y AUMENTAR la confidence en un 5 %

Cadena de evidencias en el informe

Lo que vería sin análisis multicapa

[HIGH] SQL Injection (f-string) — src/db.py:42
  Risk: An attacker can inject malicious SQL...
  Solution: Use parameterized queries.

Sin contexto. Le tocaría a usted averiguar por qué es un problema.

Lo que ve con el análisis multicapa

[HIGH] SQL Injection (f-string) — src/db.py:42
  Confidence: 95 % (pattern + taint + context)

  Evidencias:

  1. Source (línea 12):
     user_id = request.args.get('id')
     -> Datos HTTP no confiables (kind: http)

  2. Propagación (línea 38):
     query = f"SELECT * FROM users WHERE id = {user_id}"
     -> Variable inyectada en una consulta SQL mediante f-string

  3. Sink (línea 42):
     cursor.execute(query)
     -> Ejecución de la consulta sin parametrización

  4. Contexto:
     - Archivo Flask con handler HTTP (@app.route)
     - SQL en bruto (sin ORM)
     - Sin validación de entrada detectada
     - Sin sanitizer detectado

  Solution: Use parameterized queries.
  Playbook: 3 pasos (diagnóstico -> corrección -> verificación)
  References: CWE-89, OWASP A03:2021, ISO A.8.28

Usted puede verificar cada paso de la prueba. Si piensa que se trata de un falso positivo, sabe exactamente qué comprobar.


Impacto sobre los falsos positivos

La capa de contexto reduce drásticamente los falsos positivos:

Situación Sin multicapa Con multicapa
Pattern en un archivo de test Hallazgo (FP) Eliminado (is_test_file)
Pattern en un archivo con ORM Hallazgo (FP) Confidence 35 % -> eliminado
Pattern + taint confirmado Hallazgo (80 %) Hallazgo (95 %)
Pattern en un comentario/cadena Hallazgo (FP) Confidence 35 % -> eliminado

Estimación de calidad

Métrica Monocapa Multicapa
Precisión 81 % 93 %+ (el contexto filtra los FP)
Recall 99 % 99 % (misma cobertura)
Score F1 89 % 96 %+

Lo que el análisis multicapa NO resuelve

El análisis multicapa mejora la calidad de las detecciones existentes. No puede detectar:

  • Los bugs lógicos puros (por ejemplo, un IDOR donde el problema es un WHERE ausente en una consulta, no un patrón sintáctico)
  • Las vulnerabilidades en las dependencias (cubiertas por pip-audit / npm audit, no por SAST)
  • Las vulnerabilidades en código compilado u ofuscado

Para estos casos, las soluciones complementarias son:

  • IDOR: regla específica "CRUD sin ownership check"
  • Dependencias: opciones --with-deps (escaneo CVE) y --sbom
  • Código compilado: fuera del scope SAST