diff --git a/docs/AUDIT_Detection_vs_Thesis.md b/docs/AUDIT_Detection_vs_Thesis.md index fcf16f4..2e3551c 100644 --- a/docs/AUDIT_Detection_vs_Thesis.md +++ b/docs/AUDIT_Detection_vs_Thesis.md @@ -1,7 +1,8 @@ -# Audit de conformité : Détection de bots vs État de l'art (Thèse) +# Audit de conformité : Code vs Thèse — Mise à jour 8 avril 2026 -**Date** : 7 avril 2026 +**Date** : 8 avril 2026 **Référence** : `docs/THESIS_HTTP_Traffic_Detection.md` +**Périmètre** : `services/bot-detector/`, `services/dashboard/`, schéma SQL --- @@ -13,438 +14,268 @@ | ⚠️ PARTIEL | Implémenté mais incomplet ou dégradé | | ❌ ABSENT | Décrit dans la thèse, non implémenté | | 🔄 DIVERGENT | Implémenté différemment de ce que décrit la thèse | +| 🐛 BUG | Implémenté mais avec un bug qui empêche le fonctionnement correct | --- -## 1. Architecture multi-couches (Thèse §3) +## Partie A — Conformité bot-detector vs Thèse -### 1.1 Pipeline global +### A1. Architecture multi-couches (Thèse §3) -| Composant thèse | Statut | Réalité | -|-----------------|--------|---------| -| Capture L3-L5 (ja4sentinel) | ✅ | Opérationnel — extraction TTL, IP-ID, DF, TCP win/mss/scale, JA4/JA3, ALPN, SNI | -| Capture L7 (mod_reqin_log) | ✅ | Opérationnel — headers, méthode, path, query, timestamps ns | -| Corrélation inter-couches (logcorrelator) | ✅ | Clé `src_ip:src_port`, Keep-Alive, orphelins, fenêtre 10s | -| Enrichissement GeoIP/ASN à l'ingestion | ✅ | `dict_iplocate_asn` dans `mv_http_logs` | -| Enrichissement Anubis à l'ingestion | ✅ | 5 niveaux de priorité (UA+IP > UA > IP > ASN > Country) | -| Agrégation temporelle 1h | ✅ | `agg_host_ip_ja4_1h` + `agg_header_fingerprint_1h` via MV | -| Détection ML semi-supervisée | ✅ | Dual IsolationForest (Complet/Applicatif), cycle 5min | -| Dashboard SOC | ✅ | 21+ routes, clustering, fingerprints, incidents | +| Composant thèse | Statut | Détail | +|-----------------|--------|--------| +| Pipeline L3-L5 (ja4sentinel) | ✅ | TTL, IP-ID, DF, TCP win/mss/scale, JA4/JA3, ALPN, SNI | +| Pipeline L7 (mod_reqin_log) | ✅ | Headers, méthode, path, query, timestamps ns | +| Corrélation (logcorrelator) | ✅ | Clé `src_ip:src_port`, Keep-Alive, orphelins | +| Enrichissement ASN | ✅ | `dict_iplocate_asn` (714K CIDRs, 4 colonnes) | +| Enrichissement Anubis | ✅ | 5 niveaux priorité (UA+IP > UA > IP > ASN > Country) | +| Agrégation 1h | ✅ | `agg_host_ip_ja4_1h` + `agg_header_fingerprint_1h` | +| Vue features | ✅ | `view_ai_features_1h` (72+ colonnes) | +| Bifurcation Complet/Applicatif | ✅ | Complet (63 features L3→L7, correlated=1) + Applicatif (51 features L7, correlated=0) | -**Verdict §3** : L'architecture multi-couches décrite dans la thèse est **fidèlement implémentée**. C'est le point fort de la plateforme. +### A2. Features L3 IP (Thèse §3.2) + +| Feature thèse | Statut | Colonne SQL / Python | +|--------------|--------|---------------------| +| avg_ttl | ✅ | `avg_ttl` dans `view_ai_features_1h` | +| ttl_std | ✅ | `ttl_std` | +| ip_id_zero_ratio | ✅ | `ip_id_zero_ratio` | +| ip_df_variance | ✅ | `ip_df_variance` | +| request_size_variance | ✅ | `request_size_variance` | +| anomalous_payload_ratio | ✅ | `anomalous_payload_ratio` | + +### A3. Features L4 TCP (Thèse §3.3) + +| Feature thèse | Statut | Détail | +|--------------|--------|--------| +| true_window_size | ⚠️ PARTIEL | Calculé dans SQL mais **non inclus dans `feats_complet`** — pas utilisé par l'EIF | +| window_mss_ratio | ⚠️ PARTIEL | Calculé dans SQL, **absent de `feats_complet`** | +| mss_mobile_mismatch | ✅ | Dans `feats_complet` | +| no_window_scale_ratio | ✅ | Dans `feats_complet` | +| tcp_shared_count | ✅ | Dans `feats` | +| tcp_jitter_variance | ✅ | Dans `feats_complet` | +| src_port_density | ✅ | Dans `feats` | +| port_exhaustion_ratio | ✅ | Dans `feats` | +| max_keepalives | ✅ | Dans `feats` | + +### A4. Features L5 TLS (Thèse §3.4) + +| Feature thèse | Statut | Détail | +|--------------|--------|--------| +| JA4 fingerprint | ✅ | Clé de corrélation + feature | +| is_rare_ja4 | ✅ | Dans `feats_complet` | +| ja3_diversity_ratio | ✅ | Dans `feats_complet` | +| is_alpn_missing | ✅ | Dans `feats_complet` | +| sni_host_mismatch | ✅ | Dans `feats_complet` | +| tls12_ratio | ✅ | Dans `feats_complet` | +| alpn_http_mismatch | ✅ | Dans `feats_complet` | + +### A5. Features L7 HTTP (Thèse §3.5 + §2.3) + +| Feature thèse | Statut | Détail | +|--------------|--------|--------| +| hits, hit_velocity | ✅ | | +| fuzzing_index | ✅ | | +| post_ratio, head_ratio | ✅ | | +| asset_ratio, direct_access_ratio | ✅ | | +| modern_browser_score | ✅ | 0/50/100 | +| ua_ch_mismatch | ✅ | | +| has_accept_language, has_cookie, has_referer | ✅ | | +| sec_fetch_absence_rate | ✅ | | +| generic_accept_ratio | ✅ | | +| missing_accept_enc_ratio | ✅ | | +| header_count, header_order_confidence | ✅ | | +| temporal_entropy | ✅ | Shannon entropie | +| path_diversity_ratio, url_depth_variance | ✅ | | +| http10_ratio, http_scheme_ratio | ✅ | | +| orphan_ratio | ✅ | | +| is_ua_rotating | ✅ | | + +### A6. ML Pipeline (Thèse §2.4 + §3.8) + +| Élément thèse | Statut | Détail | +|---------------|--------|--------| +| Extended Isolation Forest (EIF) | ✅ | `isotree` lib, ntrees=300, contamination=0.001 | +| Bifurcation Complet/Applicatif | ✅ | Deux modèles par cycle | +| Baseline ISP (humaine) | ✅ | `asn_label == 'isp'` (anciennement 'human') | +| Seuil adaptatif | ✅ | `min(percentile_5, -0.05)` | +| Threat levels | ✅ | CRITICAL/HIGH/MEDIUM/LOW/NORMAL + KNOWN_BOT + ANUBIS_DENY | +| Autoencoder | ✅ | PyTorch, architecture n→64→32→16→32→64→n, reconstruction error | +| XGBoost supervisé | ✅ | Labels SOC, retraining conditionnel | +| Ensemble triple voix | ⚠️ PARTIEL | Combinaison linéaire `(1-β)*((1-α)*eif + α*ae) + β*xgb`. **Meta-learner (régression logistique) absent** — la thèse préconise un meta-learner appris, pas une pondération fixe | +| Dérive conceptuelle (KS test) | 🔄 DIVERGENT | Implémentation utilise des quantiles reconstruits (5 points p10-p90) au lieu du test KS complet sur la distribution. Approximation grossière pour distributions multimodales | +| Validation gate | ✅ | Taux anomalie >20% → rejet modèle | +| Feature pruning (variance) | ✅ | Seuil 1e-6 | +| SHAP explainability | ✅ | Top-5 features par anomalie | +| HDBSCAN clustering | ✅ | Campagnes coordonnées | +| Feedback loop SOC | ✅ | FP→baseline, TP→exclusion | +| Déduplication TTL | ✅ | Inter-cycles, configurable | +| Récurrence penalty | ✅ | log1p(recurrence) × weight | +| Browser légitime (LEGITIMATE_BROWSER) | ✅ | JA4 + consistency score ≥ 4/5 | + +### A7. Techniques originales (Thèse §5) + +| Technique | Statut | Détail | +|-----------|--------|--------| +| §5.1 Path Sequence Entropy | ✅ | `path_transition_entropy` dans `view_thesis_features_1h` + `feats` | +| §5.2 Bipartite JA4×ASN Graph | ❌ ABSENT | Non implémenté | +| §5.3 Request Cadence Fingerprint | ✅ | `cadence_cv`, `burst_ratio`, `pause_ratio`, `lag1_autocorrelation`, `benford_deviation` | +| §5.4 Resource Dependency Tree | 🐛 BUG | SQL calcule `root_to_first_asset_delay` et `asset_load_stddev` mais **`view_resource_cascade_1h` n'est PAS jointe dans `view_thesis_features_1h`** — features inaccessibles au bot_detector | +| §5.5 Intra-Session JA4 Drift | ✅ | `ja4_drift_ratio` dans `view_thesis_features_1h` + `feats_complet` | +| §5.6 DNS Shadow Analysis | ❌ ABSENT | Nécessite extension ja4sentinel pour capture DNS (UDP/53) | +| §5.7 Compression Ratio Invariant | ❌ ABSENT | Nécessite instrumentation côté serveur Apache | +| §5.8 Cross-Domain Session Linking | ✅ | `host_diversity`, `host_sweep_speed`, `host_coverage_uniformity` dans `view_thesis_features_1h` + `feats` | + +### A8. Taxonomie 7 familles (Thèse §4) + +| Famille | Features attendues | Statut | +|---------|-------------------|--------| +| 1. Volume & Vitesse | hits, hit_velocity, max_keepalives | ✅ 3/3 | +| 2. Diversité & Exploration | fuzzing_index, path_diversity_ratio, url_depth_variance, distinct_ja4_count, distinct_header_orders, is_ua_rotating | ✅ 6/6 | +| 3. Authenticité protocolaire | modern_browser_score, ua_ch_mismatch, has_accept_language, has_cookie, has_referer, sec_fetch_absence_rate, generic_accept_ratio, missing_accept_enc_ratio, header_count, header_order_confidence | ✅ 10/10 | +| 4. Cohérence cross-layer | alpn_http_mismatch, is_alpn_missing, sni_host_mismatch, mss_mobile_mismatch, tls12_ratio, http10_ratio, tcp_jitter_variance, syn_timing_cv | ✅ 8/8 | +| 5. Empreinte réseau | ip_id_zero_ratio, request_size_variance, anomalous_payload_ratio, avg_ttl, ttl_std, no_window_scale_ratio, ip_df_variance, tcp_shared_count, port_exhaustion_ratio, src_port_density | ✅ 10/10 | +| 6. Comportement navigateur | asset_ratio, direct_access_ratio, orphan_ratio, temporal_entropy, post_ratio, head_ratio, http_scheme_ratio | ✅ 7/7 | +| 7. Intelligence contextuelle | ja4_asn_concentration, ja4_country_concentration, is_rare_ja4, header_order_shared_count, ja3_diversity_ratio, anubis_is_flagged, multiplexing_efficiency | ✅ 7/7 | + +**Total taxonomie : 51/51 features (100%)** --- -## 2. Couche L3 — IP et paquets (Thèse §3.2) +## Partie B — Bugs identifiés dans bot-detector -| Signal thèse | Feature implémentée | Statut | -|--------------|---------------------|--------| -| TTL initial caractéristique de l'OS | `avg_ttl` (feature #49) | ✅ | -| Déviation TTL (`ttl_std`) | `ttl_std` (feature #50) | ✅ | -| IP ID à zéro → paquets forgés | `ip_id_zero_ratio` (feature #16) | ✅ | -| Variance bit DF | `ip_df_variance` (feature #48) | ✅ | -| Variance Total Length | `request_size_variance` (feature #17) | ✅ | -| Anomalous payload ratio (<60 ou >1500) | `anomalous_payload_ratio` (feature #33) | ✅ | +### B1. Bugs critiques (impact fonctionnel) -**Verdict L3** : ✅ **100% conforme**. Tous les signaux L3 décrits dans la thèse sont implémentés. +| # | Sévérité | Description | Localisation | +|---|----------|-------------|-------------| +| B1.1 | 🔴 | `campaign_id` jamais inséré dans `ml_detected_anomalies` — toujours DEFAULT -1 malgré le calcul HDBSCAN | `bot_detector.py` cols ligne ~1624 | +| B1.2 | 🔴 | `raw_anomaly_score` jamais inséré dans `ml_detected_anomalies` — toujours DEFAULT 0 | `bot_detector.py` cols ligne ~1624 | +| B1.3 | 🔴 | `view_ip_recurrence` utilise `min(anomaly_score)` pour `worst_score` — avec scores normalisés (0=normal, 1=anomal), min() retourne le score le MOINS anormal | `06_ml_tables.sql` | +| B1.4 | 🟠 | `log_decision('FEATURE_PRUNED', name, '', ...)` — `name` passé en `cycle_id` au lieu de `model` (argument order swap) | `bot_detector.py:596` | +| B1.5 | 🟠 | `log_decision('MODEL_REJECTED', name, '', ...)` — même inversion d'arguments | `bot_detector.py:623` | +| B1.6 | 🟠 | Anubis ALLOW bots : `bot_name` reste vide dans `ml_detected_anomalies` car sélectionnés via `rest[bot_name == '']` | `bot_detector.py:970-1140` | +| B1.7 | 🟠 | AE scoring échoue avec erreur broadcast `(N,50) vs (37,)` quand le nombre de features après élagage diffère du training | Logs cycle — AE trained sur 37 features, scoring sur 50 | +| B1.8 | 🟡 | `rec_df` peut être `None` → `TypeError` sur `dict(zip(rec_df['src_ip']...))` | `bot_detector.py:~1489` | +| B1.9 | 🟡 | `is_headless` mappé depuis `is_fake_navigation` — mismatch sémantique | `bot_detector.py:1622` | + +### B2. Bugs qualité code + +| # | Sévérité | Description | Localisation | +|---|----------|-------------|-------------| +| B2.1 | 🟡 | `warnings.filterwarnings('ignore')` — supprime TOUS les warnings globalement | `bot_detector.py:71` | +| B2.2 | 🟡 | `pyyaml` dans requirements.txt mais jamais importé | `requirements.txt` | +| B2.3 | 🟡 | `joblib` utilisé mais non déclaré en dépendance directe (transitif via sklearn) | `requirements.txt` | +| B2.4 | 🟡 | Side-effects au niveau module (health server, signal handlers) — empêche import propre dans les tests | `bot_detector.py:232,252-259` | +| B2.5 | 🟡 | Tests réimplémentent la logique au lieu d'importer les vraies fonctions — les tests peuvent passer même si le code réel a des bugs | `test_detector.py` | +| B2.6 | 🟡 | Section header dupliquée "A5 — DÉDUPLICATION" | `bot_detector.py:1242,1280` | +| B2.7 | ⚪ | 18+ valeurs hardcodées non configurables (min baseline=500, ntrees=300, XGB limit=50000, threat level seuils, batch_size AE=256...) | Dispersé | + +### B3. Feature SQL non jointe (Thèse §5.4) + +`view_resource_cascade_1h` est définie dans `12_thesis_features.sql` mais **absente du JOIN final** dans `view_thesis_features_1h`. Les features `root_to_first_asset_delay` et `asset_load_stddev` sont calculées mais inaccessibles. + +### B4. Cross-domain features dupliquées + +Dans `view_thesis_features_1h`, le LEFT JOIN de `cross_domain_features` se fait sur `(window_start, src_ip)` sans `ja4` ni `host`. Les features `host_diversity`, `host_sweep_speed`, `host_coverage_uniformity` sont donc dupliquées pour chaque combinaison (ja4, host) d'une même IP, sur-pondérant ces features dans le modèle. --- -## 3. Couche L4 — TCP (Thèse §3.3) +## Partie C — Bugs identifiés dans dashboard -| Signal thèse | Feature implémentée | Statut | -|--------------|---------------------|--------| -| Window Size × Scale (`true_window_size`) | Composants disponibles (`tcp_window`, `tcp_scale`) mais `true_window_size` non calculé comme feature ML | ⚠️ PARTIEL | -| MSS (1460 = Ethernet, <1460 = tunnel) | `mss_mobile_mismatch` (feature #19) — utilise MSS mais uniquement pour détecter le mismatch mobile | ⚠️ PARTIEL | -| Options TCP (absence timestamp/scale) | `no_window_scale_ratio` (feature #51) | ✅ | -| `tcp_shared_count` (IPs partageant même fingerprint TCP) | Feature #8 | ✅ | -| Jitter SYN→ClientHello | `tcp_jitter_variance` (feature #41) | ✅ | -| `src_port_density` | Feature #24 | ✅ | -| Keepalive count | `max_keepalives` (feature #7) | ✅ | +### C1. Bugs critiques (sécurité) -| Lacune | Impact | -|--------|--------| -| `true_window_size` = `window × 2^scale` non calculé comme feature indépendante | **MOYEN** — le signal est partiellement capturé par le TCP fingerprinting du dashboard (poids 20% window + 10% scale séparés) mais pas fusionné pour le ML | -| MSS comme feature ML directe (pas seulement mismatch mobile) | **MOYEN** — MSS brut permettrait de distinguer Ethernet/VPN/mobile au-delà du cas mobile | +| # | Sévérité | Description | Localisation | +|---|----------|-------------|-------------| +| C1.1 | 🔴 | **XSS** : `const IP = "{{ ip }}";` — injection JS via URL `/ip/";alert(1);//` | `ip_detail.html:72`, `pages.py:37` | +| C1.2 | 🔴 | **Stored XSS** : `fmtIP()` construit du HTML brut injecté via `innerHTML` — données ClickHouse non échappées | `base.html:123`, tous les templates | +| C1.3 | 🔴 | **Aucune authentification** sur aucun endpoint — `/api/classify` (POST) écrit en DB sans auth | `main.py`, `api.py:770` | +| C1.4 | 🔴 | **Pas de CSRF** sur le POST `/api/classify` + CORS `allow_origins=["*"]` | `main.py:19-25` | -**Verdict L4** : ⚠️ **85% conforme**. Les signaux critiques sont présents, mais `true_window_size` et MSS brut manquent comme features ML directes. +### C2. Bugs fonctionnels + +| # | Sévérité | Description | Localisation | +|---|----------|-------------|-------------| +| C2.1 | 🟠 | **Filtre status cassé** : `status` query param filtre `http_version` au lieu du code HTTP — feature non fonctionnelle | `api.py:335` | +| C2.2 | 🟠 | **Heatmap jour décalé** : `toDayOfWeek()` retourne 1-7 (Lun-Dim), template attend 0-6 — Dimanche hors limites | `api.py:654`, `features.html:63` | +| C2.3 | 🟠 | **IPv4/IPv6 incohérent** : détections/scores filtrent via `toIPv6()`, http_logs via `toIPv4OrZero()` — résultats incomplets sur page IP | `api.py:378-399` | +| C2.4 | 🟠 | **CORS invalide** : `allow_origins=["*"]` avec `allow_credentials=True` — interdit par la spec CORS, les navigateurs rejettent | `main.py:19-25` | +| C2.5 | 🟡 | Bouton filtre MEDIUM manquant sur la page scores | `scores.html:22` | +| C2.6 | 🟡 | `models.html` — null safety manquante : `m.validation.val_anomaly_rate*100` crash si null | `models.html:51` | +| C2.7 | 🟡 | Erreurs internes exposées en 500 (`str(exc)` retourné au client — noms de tables, erreurs ClickHouse) | `api.py:144,226,303,364,433,787` | +| C2.8 | 🟡 | Static directory vide/manquant → crash au démarrage si inexistant | `main.py:28` | +| C2.9 | 🟡 | `/api/overview` exécute 8 requêtes séquentielles, `/api/behavior` en exécute 7 — aucune parallélisation | `api.py` | +| C2.10 | ⚪ | Aucun test unitaire ou d'intégration pour le dashboard | — | +| C2.11 | ⚪ | Dockerfile : pas de `HEALTHCHECK`, exécution root, pas de `.dockerignore` | `Dockerfile` | --- -## 4. Couche L5 — TLS (Thèse §3.4) +## Partie D — Synthèse quantitative -| Signal thèse | Feature implémentée | Statut | -|--------------|---------------------|--------| -| JA4 + rareté | `is_rare_ja4` (feature #27) | ✅ | -| JA3 diversité dans un JA4 stable | `ja3_diversity_ratio` (feature #45) | ✅ | -| ALPN absent | `is_alpn_missing` (feature #43) | ✅ | -| SNI ≠ Host | `sni_host_mismatch` (feature #44) | ✅ | -| TLS 1.2 ratio | `tls12_ratio` (feature #47) | ✅ | -| ALPN × HTTP version mismatch | `alpn_http_mismatch` (feature #42) | ✅ | +### D1. Conformité thèse -**Verdict L5** : ✅ **100% conforme**. +| Section thèse | Éléments | Conformes | Partiels | Absents | Bugs | Score | +|--------------|----------|-----------|----------|---------|------|-------| +| §3 Architecture | 8 | 8 | 0 | 0 | 0 | 100% | +| §3.2 L3 IP | 6 | 6 | 0 | 0 | 0 | 100% | +| §3.3 L4 TCP | 9 | 7 | 2 | 0 | 0 | 89% | +| §3.4 L5 TLS | 7 | 7 | 0 | 0 | 0 | 100% | +| §3.5 L7 HTTP | 17 | 17 | 0 | 0 | 0 | 100% | +| §4 Taxonomie 7 familles | 51 | 51 | 0 | 0 | 0 | 100% | +| §2.4+§3.8 ML Pipeline | 16 | 13 | 2 | 0 | 1 | 84% | +| §5 Techniques originales | 8 | 4 | 0 | 3 | 1 | 50% | +| **TOTAL** | **122** | **113** | **4** | **3** | **2** | **93%** | + +### D2. Évolution depuis le dernier audit (7 avril) + +| Métrique | 7 avril | 8 avril | Delta | +|----------|---------|---------|-------| +| §5 Techniques originales | 6% (0/8 + 1 partiel) | 50% (4/8) | **+44%** | +| Feedback loop SOC | ❌ ABSENT | ✅ CONFORME | ✅ Résolu | +| Browser classification | ❌ ABSENT | ✅ CONFORME | ✅ Résolu | +| ASN classification PeeringDB | ⚠️ 86% unknown | ✅ 7 catégories | ✅ Résolu | +| Score global pondéré | ~72% | ~93% | **+21%** | + +### D3. Gaps restants (par priorité) + +| Priorité | Gap | Impact | Effort | +|----------|-----|--------|--------| +| P0 🔴 | `campaign_id` + `raw_anomaly_score` jamais insérés | Clustering HDBSCAN inutile, score brut perdu | 5 min — ajouter aux cols | +| P0 🔴 | `worst_score` inversé dans `view_ip_recurrence` | Récurrence penalty basée sur mauvais score | 5 min — `max()` au lieu de `min()` | +| P0 🔴 | XSS dans `ip_detail.html` (injection JS) | Exécution code arbitraire | 5 min — `{{ ip \| tojson }}` | +| P0 🔴 | Stored XSS via `innerHTML` + données DB | Idem | 30 min — sanitizer ou textContent | +| P1 🟠 | AE broadcast error (features mismatch après élagage) | AE désactivé en pratique | 30 min — aligner features | +| P1 🟠 | `view_resource_cascade_1h` non jointe (§5.4) | Features thèse §5.4 inaccessibles | 15 min — ajouter LEFT JOIN | +| P1 🟠 | Anubis ALLOW `bot_name` vide | KNOWN_BOT sans identification | 5 min — assigner `anubis_bot_name` | +| P1 🟠 | Status filter cassé dans traffic | Feature non fonctionnelle | 15 min — corriger la colonne | +| P1 🟠 | Heatmap jour décalé | Dimanche non affiché | 5 min — `toDayOfWeek() - 1` | +| P2 🟡 | Meta-learner absent (thèse préconise régression logistique) | Pondération fixe vs apprise | 2h — implémenter | +| P2 🟡 | §5.2 Bipartite JA4×ASN Graph | Technique originale manquante | 4h | +| P2 🟡 | §5.6 DNS Shadow Analysis | Nécessite extension ja4sentinel | Hors scope court terme | +| P2 🟡 | §5.7 Compression Ratio Invariant | Nécessite instrumentation Apache | Hors scope court terme | +| P3 ⚪ | Authentification dashboard | Sécurité production | 4h | +| P3 ⚪ | Tests dashboard (0% coverage) | Qualité | 8h | +| P3 ⚪ | Tests bot-detector importent le vrai code | Qualité | 4h | --- -## 5. Couche L7 — HTTP (Thèse §3.5) - -| Signal thèse | Feature implémentée | Statut | -|--------------|---------------------|--------| -| HEAD requests | `head_ratio` (feature #34) | ✅ | -| HTTP/1.0 | `http10_ratio` (feature #37) | ✅ | -| Temporal entropy (Shannon) | `temporal_entropy` (feature #30) | ✅ | -| Accept-Language présent | `has_accept_language` (feature #11) | ✅ | -| Cookie présent | `has_cookie` (feature #12) | ✅ | -| Referer présent | `has_referer` (feature #13) | ✅ | -| Sec-Fetch absence | `sec_fetch_absence_rate` (feature #35) | ✅ | -| Generic Accept | `generic_accept_ratio` (feature #36) | ✅ | -| Missing Accept-Encoding | `missing_accept_enc_ratio` (feature #39) | ✅ | -| Client Hints (Sec-CH-UA) | `modern_browser_score` (feature #14) | ✅ | -| UA/Client-Hints mismatch | `ua_ch_mismatch` (feature #15) | ✅ | -| Header count | `header_count` (feature #10) | ✅ | -| Header order confidence | `header_order_confidence` (feature #28) | ✅ | - -**Verdict L7** : ✅ **100% conforme**. - ---- - -## 6. Détection ML semi-supervisée (Thèse §3.8) - -| Mécanisme thèse | Implémentation | Statut | -|-----------------|----------------|--------| -| Trifurcation (known bots → Anubis → IF) | `bot_detector.py:532-693` — exactement 3 flux | ✅ | -| Dual modèle (Complet L4+L7 / Applicatif L7-only) | 45 features (corrélé) / 37 features (non corrélé) | ✅ | -| Baseline humaine (`asn_label='human'`, min 500) | `bot_detector.py:247-290` | ✅ | -| Seuil adaptatif `min(P5, -0.05)` | `bot_detector.py:422-431` | ✅ | -| Niveaux de menace (CRITICAL/HIGH/MEDIUM/LOW) | `bot_detector.py:206-215` — seuils identiques à la thèse | ✅ | -| SHAP TreeExplainer top-5 | `bot_detector.py:458-490` | ✅ | -| DBSCAN campagnes | `bot_detector.py:496-516` | ✅ | -| Pénalité de récurrence | `bot_detector.py:576-579` | ✅ | -| Dérive conceptuelle (drift) | `bot_detector.py:329-353` | 🔄 DIVERGENT | - -### Divergence détection de dérive - -La thèse (§3.8) mentionne le test de Kolmogorov-Smirnov pour détecter la dérive. L'implémentation utilise un **Z-score sur la moyenne** (`|current_mean - trained_mean| / trained_std > 2.0`), pas un test KS. - -| Aspect | Thèse | Réalité | Impact | -|--------|-------|---------|--------| -| Méthode | Test KS (distribution complète) | Z-score (moyenne seule) | **MOYEN** — le Z-score détecte les shifts de moyenne mais manque les changements de forme de distribution (ex: bimodalité émergente) | -| Seuil | Non spécifié | 30% features driftées → retrain | Acceptable | - -**Verdict ML** : ⚠️ **95% conforme**. Seule la méthode de détection de dérive diverge. - ---- - -## 7. Taxonomie des features (Thèse §4) — Les 7 familles - -### Famille 1 : Volumétrie et vitesse -| Feature thèse | Implémentée | Statut | -|---------------|-------------|--------| -| `hits` | ✅ Feature #1 | ✅ | -| `hit_velocity` | ✅ Feature #2 | ✅ | -| `max_keepalives` | ✅ Feature #7 | ✅ | - -### Famille 2 : Diversité et exploration -| Feature thèse | Implémentée | Statut | -|---------------|-------------|--------| -| `fuzzing_index` | ✅ Feature #3 | ✅ | -| `path_diversity_ratio` | ✅ Feature #31 | ✅ | -| `url_depth_variance` | ✅ Feature #32 | ✅ | -| `distinct_ja4_count` | ✅ Feature #23 | ✅ | -| `distinct_header_orders` | ✅ Feature #29 | ✅ | -| `is_ua_rotating` | ✅ Feature #22 | ✅ | - -### Famille 3 : Authenticité protocolaire -| Feature thèse | Implémentée | Statut | -|---------------|-------------|--------| -| `modern_browser_score` | ✅ Feature #14 | ✅ | -| `ua_ch_mismatch` | ✅ Feature #15 | ✅ | -| `has_accept_language` | ✅ Feature #11 | ✅ | -| `has_cookie` | ✅ Feature #12 | ✅ | -| `has_referer` | ✅ Feature #13 | ✅ | -| `sec_fetch_absence_rate` | ✅ Feature #35 | ✅ | -| `generic_accept_ratio` | ✅ Feature #36 | ✅ | -| `missing_accept_enc_ratio` | ✅ Feature #39 | ✅ | -| `header_count` | ✅ Feature #10 | ✅ | -| `header_order_confidence` | ✅ Feature #28 | ✅ | - -### Famille 4 : Cohérence cross-layer -| Feature thèse | Implémentée | Statut | -|---------------|-------------|--------| -| `alpn_http_mismatch` | ✅ Feature #42 | ✅ | -| `is_alpn_missing` | ✅ Feature #43 | ✅ | -| `sni_host_mismatch` | ✅ Feature #44 | ✅ | -| `mss_mobile_mismatch` | ✅ Feature #19 | ✅ | -| `tls12_ratio` | ✅ Feature #47 | ✅ | -| `http10_ratio` | ✅ Feature #37 | ✅ | -| `tcp_jitter_variance` | ✅ Feature #41 | ✅ | -| `syn_timing_cv` | ✅ Feature #46 | ✅ | - -### Famille 5 : Empreinte réseau -| Feature thèse | Implémentée | Statut | -|---------------|-------------|--------| -| `ip_id_zero_ratio` | ✅ Feature #16 | ✅ | -| `request_size_variance` | ✅ Feature #17 | ✅ | -| `anomalous_payload_ratio` | ✅ Feature #33 | ✅ | -| `avg_ttl` | ✅ Feature #49 | ✅ | -| `ttl_std` | ✅ Feature #50 | ✅ | -| `no_window_scale_ratio` | ✅ Feature #51 | ✅ | -| `ip_df_variance` | ✅ Feature #48 | ✅ | -| `tcp_shared_count` | ✅ Feature #8 | ✅ | -| `port_exhaustion_ratio` | ✅ Feature #5 | ✅ | -| `src_port_density` | ✅ Feature #24 | ✅ | - -### Famille 6 : Comportement de navigation -| Feature thèse | Implémentée | Statut | -|---------------|-------------|--------| -| `asset_ratio` | ✅ Feature #20 | ✅ | -| `direct_access_ratio` | ✅ Feature #21 | ✅ | -| `orphan_ratio` | ✅ Feature #6 | ✅ | -| `temporal_entropy` | ✅ Feature #30 | ✅ | -| `post_ratio` | ✅ Feature #4 | ✅ | -| `head_ratio` | ✅ Feature #34 | ✅ | -| `http_scheme_ratio` | ✅ Feature #40 | ✅ | - -### Famille 7 : Intelligence contextuelle -| Feature thèse | Implémentée | Statut | -|---------------|-------------|--------| -| `ja4_asn_concentration` | ✅ Feature #25 | ✅ | -| `ja4_country_concentration` | ✅ Feature #26 | ✅ | -| `is_rare_ja4` | ✅ Feature #27 | ✅ | -| `header_order_shared_count` | ✅ Feature #9 | ✅ | -| `ja3_diversity_ratio` | ✅ Feature #45 | ✅ | -| `anubis_is_flagged` | ✅ Feature #38 | ✅ | -| `multiplexing_efficiency` | ✅ Feature #18 | ✅ | - -**Verdict §4** : ✅ **100% des 51 features** de la taxonomie sont implémentées. - ---- - -## 8. Techniques originales proposées (Thèse §5) — TOUTES ABSENTES - -C'est ici que la plateforme diverge massivement de l'état de l'art proposé. - -### 8.1 Path Sequence Entropy (§5.1) - -| Aspect | Thèse | Réalité | -|--------|-------|---------| -| Entropie de Markov ordre 1 sur séquences de chemins | Formule définie | ❌ NON IMPLÉMENTÉ | -| `groupArray(path)` dans l'agrégation | Requis | ❌ Absent — les agrégations ne stockent que `uniq_paths` (cardinalité), pas les séquences | -| UDF ClickHouse pour entropie de transition | Requis | ❌ Absent | - -**Impact** : La plateforme mesure la *diversité* des chemins (`path_diversity_ratio`) mais pas leur *ordre*. Un crawler parcourant `/a`, `/b`, `/c` en ordre alphabétique est indistinguable d'un humain visitant les mêmes pages de manière organique. Cette technique est **la plus impactante** des 8 car elle exploite un signal déjà partiellement capturé. - -**Prérequis d'implémentation** : -1. Ajouter `groupArray(path)(100)` dans `agg_host_ip_ja4_1h` (ou nouvelle table `agg_path_sequences_1h`) -2. UDF ClickHouse ou calcul Python dans `view_ai_features_1h` / `bot_detector.py` -3. Nouvelle feature : `path_transition_entropy` - -### 8.2 Graphe bipartite JA4×ASN (§5.2) - -| Aspect | Thèse | Réalité | -|--------|-------|---------| -| Graphe bipartite G = (JA4 ∪ ASN, E) | Formule définie | ❌ NON IMPLÉMENTÉ | -| Détection de communautés (Louvain) | Requis | ❌ Absent | -| `fleet_score` | Métrique définie | ❌ Absent | - -**Impact** : `ja4_asn_concentration` détecte quand un JA4 est concentré dans un ASN, mais ne détecte pas les **flottes distribuées** utilisant N JA4 × M ASN. Un botnet rotatif avec 10 JA4 sur 50 ASN est invisible avec les features actuelles car chaque paire (JA4, ASN) paraît banale individuellement. - -**Prérequis** : Bibliothèque Python `networkx` ou `igraph`, calcul batch dans `bot_detector.py` (pas en SQL — trop complexe pour ClickHouse). - -### 8.3 Request Cadence Fingerprint (§5.3) - -| Aspect | Thèse | Réalité | -|--------|-------|---------| -| CV des intervalles inter-requêtes | Formule définie | ❌ NON IMPLÉMENTÉ | -| Autocorrélation lag-1 | Formule définie | ❌ NON IMPLÉMENTÉ | -| Ratio burst/pause | Formule définie | ❌ NON IMPLÉMENTÉ | -| Loi de Benford sur Δt | Formule définie | ❌ NON IMPLÉMENTÉ | - -**Impact** : Actuellement, `hit_velocity` (moyenne) et `temporal_entropy` (distribution horaire) sont les seuls signaux temporels. Le *rythme* précis des requêtes est un signal extrêmement discriminant : un bot avec `sleep(1.0)` a un CV ≈ 0.01, un humain a un CV ≈ 2.0. C'est la **deuxième technique la plus impactante**. - -**Prérequis** : -1. `groupArray(time)(1000)` dans l'agrégation (ou table dédiée) -2. Calcul `arrayDifference()` + `arrayReduce('stddevPop', ...)` / `arrayReduce('avg', ...)` en SQL -3. 4 nouvelles features : `cadence_cv`, `cadence_autocorr_lag1`, `burst_pause_ratio`, `benford_deviation` - -### 8.4 Resource Dependency Tree (§5.4) - -| Aspect | Thèse | Réalité | -|--------|-------|---------| -| Cascade HTML→CSS→JS→Images | Formule définie | ❌ NON IMPLÉMENTÉ | -| Délai racine→première-feuille | Métrique définie | ❌ NON IMPLÉMENTÉ | -| Simultanéité des feuilles | Métrique définie | ❌ NON IMPLÉMENTÉ | - -**Impact** : `asset_ratio` détecte les bots qui ne chargent pas les assets, mais les scrapers modernes (Playwright) les chargent tous. Seul l'*ordre temporel* des chargements les trahit. Impact moyen car requiert des données intra-page-view qui ne sont pas dans les agrégations actuelles. - -**Prérequis** : Préserver l'ordre temporel intra-session dans les agrégations, distinguer HTML/CSS/JS/image par extension ou Accept header. - -### 8.5 Intra-Session JA4 Drift (§5.5) - -| Aspect | Thèse | Réalité | -|--------|-------|---------| -| Segmentation 10min + JA4 dominant | Formule définie | ❌ NON IMPLÉMENTÉ | -| Drift ratio (transitions / segments) | Formule définie | ❌ NON IMPLÉMENTÉ | -| Corrélation drift × changement de comportement | Décrit | ❌ NON IMPLÉMENTÉ | - -**Impact** : `distinct_ja4_count` compte les JA4 distincts mais ne capture pas le *moment* du changement. Un APT changeant d'outil en cours de session (reconnaissance GET → exploitation POST) serait détecté comme `distinct_ja4_count=2` sans contexte temporel. Impact modéré — nécessite des sessions longues (>10min) et des attaquants sophistiqués. - -**Prérequis** : `groupArray(ja4)` ordonnée par time dans l'agrégation, calcul de transitions en SQL ou Python. - -### 8.6 DNS Shadow Analysis (§5.6) - -| Aspect | Thèse | Réalité | -|--------|-------|---------| -| Capture DNS passive (UDP/53) | Requis | ❌ ja4sentinel ne capture PAS le DNS | -| `dns_shadow_ratio` | Formule définie | ❌ NON IMPLÉMENTÉ | - -**Impact** : Technique puissante (bots avec /etc/hosts ou DoH privé sont invisibles aux DNS locaux) mais nécessite une **extension majeure de ja4sentinel** pour capturer les paquets UDP/53. Coût d'implémentation élevé. - -**Prérequis** : Modifier `capture.go` pour capturer UDP/53, nouveau type de log réseau, nouveau pipeline de corrélation DNS↔HTTP. - -### 8.7 Compression Ratio Invariant (§5.7) - -| Aspect | Thèse | Réalité | -|--------|-------|---------| -| Ratio compression effectif par session | Requis | ❌ NON IMPLÉMENTÉ | -| Timing post-Brotli vs post-gzip | Requis | ❌ NON IMPLÉMENTÉ | - -**Impact** : Nécessite une **instrumentation côté serveur** (Apache) pour mesurer les tailles pré/post-compression. Le module `mod_reqin_log` ne capture pas ces métriques. Coût d'implémentation élevé. - -**Prérequis** : Modifier `mod_reqin_log.c` pour capturer `Content-Length` pré-compression et taille envoyée, propager dans le log JSON. - -### 8.8 Cross-Domain Session Linking (§5.8) - -| Aspect | Thèse | Réalité | -|--------|-------|---------| -| Host diversity par IP | Partiellement — `view_dashboard_entities` fait un UNION ALL par host | ⚠️ PARTIEL | -| Host sweep speed | Formule définie | ❌ NON IMPLÉMENTÉ | -| Host coverage uniformity | Formule définie | ❌ NON IMPLÉMENTÉ | -| Cross-domain path similarity (Jaccard) | Formule définie | ❌ NON IMPLÉMENTÉ | - -**Impact** : L'agrégation actuelle est par `(window, src_ip, ja4, host)` — un scan horizontal sur 10 vhosts apparaît comme 10 lignes distinctes sans score cross-domain. Le dashboard (`view_dashboard_entities`) calcule des statistiques par entité mais **pas de features ML cross-domain**. Impact significatif en environnement multi-host. - -**Prérequis** : -1. Nouvelle vue d'agrégation par `(window, src_ip)` sans décomposition par host -2. Features : `host_diversity`, `host_sweep_speed`, `host_coverage_uniformity` -3. Calcul Jaccard en Python (trop complexe pour SQL natif) - ---- - -## 9. Lacunes additionnelles identifiées (au-delà de la thèse) - -### 9.1 Boucle de feedback supervisée - -| Aspect | Thèse §6.2 | Réalité | Statut | -|--------|-------------|---------|--------| -| Les classifications SOC devraient être réinjectées dans l'entraînement | Mentionné comme piste | `audit_logs` + `/api/analysis/{ip}/classify` existent mais ne sont JAMAIS lus par `bot_detector.py` | ❌ ABSENT | - -**Impact CRITIQUE** : Le SOC classifie des IPs (vrai positif / faux positif), mais cette connaissance est perdue. Le modèle ne s'améliore jamais à partir du feedback humain. C'est le **manque le plus fondamental** de la plateforme. - -### 9.2 Détection brute-force - -| Aspect | Thèse §3.5 | Réalité | Statut | -|--------|-------------|---------|--------| -| Analyse comportementale HTTP riche | Décrit | `POST >= 10` en 24h seulement | ⚠️ MINIMALISTE | - -La détection brute-force ignore : les codes de réponse (401/403), les timing patterns, le ratio succès/échec, la diversité des credentials (estimable via query param diversity). - -### 9.3 DBSCAN non-adaptatif - -| Aspect | Thèse §3.8 | Réalité | Statut | -|--------|-------------|---------|--------| -| Détection de campagnes | DBSCAN décrit | `eps=0.5` hardcodé, `min_samples=3` | ⚠️ PARTIEL | - -**Impact** : `eps=0.5` est un choix arbitraire. Selon la distribution des données, cela peut fusionner des campagnes distinctes ou fragmenter une campagne en micro-clusters. L'état de l'art recommande HDBSCAN (adaptatif, sans eps) ou au minimum un tuning automatique via silhouette score. - -### 9.4 TCP fingerprinting statique - -| Aspect | Thèse §3.3 | Réalité | Statut | -|--------|-------------|---------|--------| -| p0f-style extensible | Référencé | 27 signatures codées en dur | ⚠️ PARTIEL | - -La base de signatures n'est pas extensible par configuration. Pas de mise à jour communautaire (contrairement à p0f qui a une base maintenue). - -### 9.5 Vérification active - -| Aspect | Thèse §2.5 | Réalité | Statut | -|--------|-------------|---------|--------| -| Challenges JS, CAPTCHA, browser fingerprinting | État de l'art décrit (BotD, etc.) | **ZÉRO** vérification active | ❌ ABSENT | - -La plateforme est **100% passive**. Aucun challenge n'est envoyé aux clients suspects. C'est un choix architectural (pas de modification du trafic), mais la thèse le mentionne comme état de l'art. - ---- - -## 10. Synthèse quantitative - -### Conformité par section - -| Section thèse | Items | Conformes | Partiels | Absents | Score | -|---------------|-------|-----------|----------|---------|-------| -| §3 Architecture | 8 | 8 | 0 | 0 | **100%** | -| §3.2 L3 IP | 6 | 6 | 0 | 0 | **100%** | -| §3.3 L4 TCP | 7 | 5 | 2 | 0 | **86%** | -| §3.4 L5 TLS | 6 | 6 | 0 | 0 | **100%** | -| §3.5 L7 HTTP | 13 | 13 | 0 | 0 | **100%** | -| §3.8 ML | 9 | 8 | 0 | 1 | **89%** | -| §4 Taxonomie (51 features) | 51 | 51 | 0 | 0 | **100%** | -| §5 Techniques originales | 8 | 0 | 1 | 7 | **6%** | - -### Score global - -| Catégorie | Score | -|-----------|-------| -| **Base existante** (§2-4) : features, pipeline, ML | **97%** conforme | -| **Techniques avancées** (§5) : les 8 innovations | **6%** conforme | -| **Score pondéré global** | **~72%** | - ---- - -## 11. Plan d'action par priorité d'impact - -### Priorité 1 — Impact maximal, coût modéré - -| # | Action | Technique thèse | Effort | Impact détection | -|---|--------|----------------|--------|-----------------| -| 1 | **Boucle de feedback supervisée** | §6.2 | Moyen | 🔴 CRITIQUE — sans cela le modèle ne s'améliore jamais | -| 2 | **Request Cadence Fingerprint** | §5.3 | Moyen | 🔴 CRITIQUE — discrimine immédiatement bots réguliers vs humains | -| 3 | **Path Sequence Entropy** | §5.1 | Moyen | 🟠 ÉLEVÉ — distingue crawlers systématiques vs navigation organique | -| 4 | **Cross-Domain Session Linking** (features ML) | §5.8 | Faible | 🟠 ÉLEVÉ — scan horizontal invisible actuellement | - -### Priorité 2 — Impact significatif, coût modéré - -| # | Action | Technique thèse | Effort | Impact détection | -|---|--------|----------------|--------|-----------------| -| 5 | **HDBSCAN** remplacer DBSCAN | §3.8 | Faible | 🟡 MOYEN — meilleure détection de campagnes | -| 6 | **Drift KS** remplacer Z-score | §3.8 | Faible | 🟡 MOYEN — détection de dérive plus robuste | -| 7 | **Bipartite Fleet Graph** | §5.2 | Élevé | 🟡 MOYEN — botnets distribués à JA4/ASN rotatifs | -| 8 | **Intra-Session JA4 Drift** | §5.5 | Moyen | 🟡 MOYEN — APT multi-phases | -| 9 | **true_window_size** + MSS brut comme features | §3.3 | Faible | 🟡 MOYEN — meilleur fingerprinting L4 | - -### Priorité 3 — Impact modéré, coût élevé - -| # | Action | Technique thèse | Effort | Impact détection | -|---|--------|----------------|--------|-----------------| -| 10 | **Resource Dependency Tree** | §5.4 | Élevé | 🟡 MOYEN — Playwright/headless | -| 11 | **TCP fingerprint extensible** (p0f-style) | §3.3 | Moyen | 🟢 FAIBLE — 27 signatures couvrent le gros | -| 12 | **Brute-force avancée** (codes réponse, timing) | §3.5 | Moyen | 🟡 MOYEN | - -### Priorité 4 — Nécessite modifications architecturales - -| # | Action | Technique thèse | Effort | Impact détection | -|---|--------|----------------|--------|-----------------| -| 13 | **DNS Shadow Analysis** | §5.6 | Très élevé | 🟠 ÉLEVÉ — requiert extension sentinel UDP/53 | -| 14 | **Compression Ratio Invariant** | §5.7 | Très élevé | 🟡 MOYEN — requiert modification mod_reqin_log | -| 15 | **Vérification active** (JS challenges) | §2.5 | Très élevé | 🟠 ÉLEVÉ — changement de paradigme | - ---- - -## 12. Conclusion - -La plateforme ja4-platform implémente **fidèlement 97% de la base** décrite dans la thèse : l'architecture multi-couches, les 51 features des 7 familles, le pipeline ML semi-supervisé avec trifurcation, SHAP, DBSCAN, et récurrence. C'est un acquis solide. - -**Le fossé majeur est dans les techniques avancées** (§5 de la thèse) : aucune des 8 techniques originales n'est implémentée. Ces techniques exploitent des signaux **temporels** (séquences de chemins, cadence inter-requêtes), **structurels** (graphes JA4×ASN), et **cross-domain** (sessions multi-host) qui sont les angles morts de la détection actuelle. - -**La lacune la plus critique** n'est pas une technique spécifique mais l'absence de **boucle de feedback** : les classifications SOC sont stockées mais jamais réinjectées dans l'entraînement, empêchant toute amélioration itérative du modèle. - -**Pour atteindre l'état de l'art sans concession**, les actions 1 à 4 du plan (feedback loop, cadence fingerprint, path entropy, cross-domain linking) couvrent ~80% de l'écart restant avec un coût d'implémentation modéré. +## Partie E — Conformité dashboard vs architecture thèse (§3.1) + +La thèse décrit le dashboard comme composant de "21 modules + clustering + outils SOC". État actuel : + +| Module thèse | Statut | Pages/Endpoints | +|-------------|--------|-----------------| +| Vue d'ensemble (overview) | ✅ | `/overview` — stats agrégées, top IPs, top JA4 | +| Détections (anomalies) | ✅ | `/detections` — tri, filtres, pagination | +| Scores ML (all_scores) | ✅ | `/scores` — toutes les sessions scorées | +| Trafic brut | ⚠️ PARTIEL | `/traffic` — filtre status cassé (C2.1) | +| Détail IP | ⚠️ PARTIEL | `/ip/` — XSS (C1.1), pas de pagination | +| Géolocalisation | ✅ | `/api/geo` — carte pays | +| Fingerprints JA4 | ✅ | `/api/fingerprints` — top JA4 avec stats | +| Features avancées | ⚠️ PARTIEL | `/features` — heatmap décalé (C2.2) | +| Comportement | ✅ | `/api/behavior` — scatter + distributions | +| Modèles ML | ⚠️ PARTIEL | `/models` — null safety (C2.6) | +| Classification SOC | ✅ | `/classify` — feedback loop | +| Réseau | ✅ | `/network` — ASN/pays | +| Browser stats | ✅ | Via `/api/overview` — navigateurs JA4 | +| Authentification | ❌ ABSENT | Aucune (C1.3) | +| CSRF protection | ❌ ABSENT | Aucune (C1.4) |