Skip to main content

Analyse multi-couches

Niveau Avancé
Temps de lecture ⏱ 15 min
mots 1271
Sujets securitytaint

Analyse Multi-Couches

Sommaire

  1. Objectif
  2. Architecture actuelle (mono-couche)
  3. Architecture proposee (multi-couches)
  4. Couche 1 : Pattern matching
  5. Couche 2 : Taint analysis
  6. Couche 3 : Context analysis
  7. Fusionneur de preuves
  8. Chaine de preuves dans le rapport
  9. Impact sur les faux positifs
  10. Limites

Objectif

Passer d'une analyse mono-couche (un seul mode par regle) a une analyse multi-couches ou chaque fichier est examine par 3 strategies independantes. Les resultats sont croises pour produire des findings a haute confiance avec une chaine de preuves verifiable par un humain.


Architecture proposee (multi-couches)

Pour chaque fichier, 3 couches s'executent en parallele :

                    ┌─────────────────┐
                    │  Fichier source  │
                    └────────┬────────┘
                             │
              ┌──────────────┼──────────────┐
              │              │              │
              ▼              ▼              ▼
     ┌────────────┐  ┌────────────┐  ┌────────────┐
     │  Couche 1   │  │  Couche 2   │  │  Couche 3   │
     │  Pattern    │  │  Taint      │  │  Context    │
     │  matching   │  │  analysis   │  │  analysis   │
     └──────┬─────┘  └──────┬─────┘  └──────┬─────┘
            │               │               │
            ▼               ▼               ▼
     ┌─────────────────────────────────────────┐
     │           Fusionneur de preuves          │
     │                                         │
     │  Croise les resultats des 3 couches.    │
     │  Calcule la confidence reelle.          │
     │  Construit la chaine de preuves.        │
     └────────────────┬────────────────────────┘
                      │
                      ▼
              ┌───────────────┐
              │   Finding     │
              │  + preuves    │
              │  + confidence │
              └───────────────┘

Couche 1 : Pattern matching (existant, ameliore)

Ce qu'elle fait

Cherche des patterns syntaxiques dans le code (texte ou regex). C'est la couche actuelle — rapide, large couverture.

Ce qu'elle produit

{
  "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\"' matche a la ligne 42"
}

Confiance seule : 65%

Un pattern match seul est un signal, pas une preuve. Le pattern peut matcher du code safe (ex: un test, un commentaire, une string de documentation).


Couche 2 : Taint analysis (existant, enrichi)

Ce qu'elle fait

Trace le flux de donnees depuis une source non fiable (input HTTP, CLI, fichier) jusqu'a un sink dangereux (execute, open, system).

Ce qu'elle produit

{
  "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": "Donnee HTTP (request.args) propage sans sanitization jusqu'a cursor.execute()"
}

Confiance seule : 85%

Un taint flow est une preuve forte — il montre le chemin complet. Mais il peut etre un faux positif si le sanitizer est dans une fonction appelee indirectement (hors du fichier).


Couche 3 : Context analysis (nouveau)

Ce qu'elle fait

Analyse le contexte du fichier pour renforcer ou infirmer les findings des couches 1 et 2. Repond a des questions :

  • Le fichier utilise-t-il un ORM (SQLAlchemy, Django ORM) ? Si oui, une injection SQL est moins probable.

  • Le fichier importe-t-il un framework de sanitization ?

  • Le fichier est-il un test, un mock, un fixture ? Si oui, ignorer.
  • Le fichier gere-t-il des requetes HTTP (routes, handlers) ?
  • Le fichier contient-il des validations d'input (schemas, validators) ?

Ce qu'elle produit

{
  "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": "Fichier Flask avec SQL brut, pas d'ORM, pas de validation d'input"
}

Signaux detectes

La couche contexte combine des heuristiques file-level :

  • Detection de fichier de test/mock/fixture (chemin contient test_, _test., mock, fixture, spec.).
  • Presence d'un ORM (SQLAlchemy, Django ORM, Tortoise, Peewee, Prisma...).
  • Presence de SQL brut (SELECT, INSERT, UPDATE, DELETE).
  • Presence d'un handler HTTP (Flask @app.route, FastAPI @router.*, async (request)...).
  • Presence d'une validation d'input (Pydantic, Marshmallow, Cerberus, WTForms, Django forms...).
  • Presence d'un sanitizer (Bleach, html.escape, MarkupSafe, parameterize, quote()...).

Retour au sommaire


Fusionneur de preuves

Calcul de la confidence

La confidence finale n'est pas une moyenne — c'est un calcul base sur les preuves independantes :

Confidence = base + bonus_taint + bonus_context - penalites

Cas concrets :

  Pattern seul, pas de contexte :
    65% (signal faible, peut etre un faux positif)

  Pattern + contexte confirme (raw SQL, pas d'ORM, handler HTTP) :
    65% + 15% = 80%

  Pattern + taint flow (source → sink confirme) :
    65% + 25% = 90%

  Pattern + taint + contexte (triple confirmation) :
    65% + 25% + 10% = 95% (quasi-certain)

  Pattern + contexte INFIRME (ORM present, fichier de test) :
    65% - 30% = 35% (probablement faux positif → supprime du rapport)

Regles de fusion

1. Si la couche contexte detecte un fichier de test → SUPPRIMER le finding
    (les fichiers de test contiennent du code vulnerable volontairement)

2. Si la couche taint confirme le flux → AUGMENTER la confidence
    et AJOUTER la chaine de preuves au finding

3. Si la couche contexte infirme (ORM present, sanitizer trouve) →
    DIMINUER la confidence. Si < 40% → SUPPRIMER le finding

4. Si deux regles differentes detectent la meme vuln au meme endroit →
    FUSIONNER en un seul finding avec la confidence la plus haute

5. Si le taint flow traverse plusieurs fichiers → AJOUTER le label
    "cross-file" et AUGMENTER la confidence de 5%

Chaine de preuves dans le rapport

Ce que le developpeur voit aujourd'hui

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

Pas de contexte. Le dev doit comprendre seul pourquoi c'est un probleme.

Ce que le developpeur verrait avec l'analyse multi-couches

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

  Preuves :

  1. Source (ligne 12) :
     user_id = request.args.get('id')
     → Donnee HTTP non fiable (kind: http)

  2. Propagation (ligne 38) :
     query = f"SELECT * FROM users WHERE id = {user_id}"
     → Variable injectee dans une requete SQL via f-string

  3. Sink (ligne 42) :
     cursor.execute(query)
     → Execution de la requete sans parametrisation

  4. Contexte :
     - Fichier Flask avec handler HTTP (@app.route)
     - SQL brut (pas d'ORM)
     - Pas de validation d'input detectee
     - Pas de sanitizer detecte

  Solution: Use parameterized queries.
  Playbook: 3 etapes (diagnostic → correction → verification)
  References: CWE-89, OWASP A03:2021, ISO A.8.28

Le developpeur peut verifier chaque etape de la preuve. S'il pense que c'est un faux positif, il sait exactement quoi verifier.


Impact sur les faux positifs

La couche contexte reduit drastiquement les faux positifs :

Situation Aujourd'hui Multi-couches
Pattern dans un fichier de test Finding (FP) Supprime (is_test_file)
Pattern dans un fichier avec ORM Finding (FP) Confidence 35% → supprime
Pattern + taint confirme Finding (80%) Finding (95%)
Pattern dans un commentaire/string Finding (FP) Confidence 35% → supprime

Estimation sur le benchmark actuel

Metrique Actuel Multi-couches (estime)
Precision 81% 93%+ (contexte filtre les FP)
Rappel 99% 99% (meme couverture)
Score F1 89% 96%+

Limites

L'analyse multi-couches ameliore la qualite des detections existantes. Elle ne peut pas detecter :

  • Les bugs logiques purs (ex: IDOR Lunary CVE-2024-1625 ou le probleme est un WHERE manquant dans une requete — pas un pattern syntaxique)

  • Les vulnerabilites dans les dependances (couvert par pip-audit, pas par SAST)

  • Les vulnerabilites dans du code compile/obfusque

Pour ces cas, les solutions sont :

  • IDOR : regle specifique "CRUD sans ownership check" (regle 4 du BountyBench)
  • Dependances : scan pip-audit/npm audit (deja implemente)
  • Code compile : hors scope SAST