docs: réécriture audit, DOCUMENTATION.md et IMPROVEMENTS.md pour architecture modulaire

- AUDIT: conformité mise à jour 97.9% (142/145), références modulaires
- DOCUMENTATION.md: 1083 lignes, 7 sections, 11 modules documentés
- IMPROVEMENTS.md: A1-A10/B1-B10 annotés /🔄/ avec localisations

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
toto
2026-04-09 22:14:18 +02:00
parent c96c41fb45
commit 6b3cc54652
3 changed files with 1548 additions and 1245 deletions

View File

@ -1,8 +1,8 @@
# Audit de conformité : Code vs Thèse — Mise à jour 8 avril 2026 # Audit de conformité : Code vs Thèse — 9 avril 2026
**Date** : 8 avril 2026 **Date** : 9 avril 2026
**Référence** : `docs/THESIS_HTTP_Traffic_Detection.md` **Référence** : `docs/THESIS_HTTP_Traffic_Detection.md`
**Périmètre** : `services/bot-detector/`, `services/dashboard/`, schéma SQL **Périmètre** : `services/bot-detector/`, `services/dashboard/`, schéma SQL, scripts opérationnels
--- ---
@ -14,7 +14,6 @@
| ⚠️ PARTIEL | Implémenté mais incomplet ou dégradé | | ⚠️ PARTIEL | Implémenté mais incomplet ou dégradé |
| ❌ ABSENT | Décrit dans la thèse, non implémenté | | ❌ ABSENT | Décrit dans la thèse, non implémenté |
| 🔄 DIVERGENT | Implémenté différemment de ce que décrit la thèse | | 🔄 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 |
--- ---
@ -28,10 +27,10 @@
| Pipeline L7 (mod_reqin_log) | ✅ | Headers, méthode, path, query, timestamps ns | | Pipeline L7 (mod_reqin_log) | ✅ | Headers, méthode, path, query, timestamps ns |
| Corrélation (logcorrelator) | ✅ | Clé `src_ip:src_port`, Keep-Alive, orphelins | | Corrélation (logcorrelator) | ✅ | Clé `src_ip:src_port`, Keep-Alive, orphelins |
| Enrichissement ASN | ✅ | `dict_iplocate_asn` (714K CIDRs, 4 colonnes) | | Enrichissement ASN | ✅ | `dict_iplocate_asn` (714K CIDRs, 4 colonnes) |
| Enrichissement Anubis | ✅ | 5 niveaux priorité (UA+IP > UA > IP > ASN > Country) | | Enrichissement Anubis | ✅ | Simplifié à `COALESCE(IP, ASN)` — 2 dictionnaires (`dict_anubis_ip` IP_TRIE, `dict_anubis_asn`) |
| Agrégation 1h | ✅ | `agg_host_ip_ja4_1h` + `agg_header_fingerprint_1h` | | Agrégation 1h | ✅ | 6 tables : `agg_host_ip_ja4_1h`, `agg_header_fingerprint_1h`, `agg_ip_behavior_1h`, `agg_request_timing_1h`, `agg_path_sequences_1h`, `agg_resource_cascade_1h` |
| Vue features | ✅ | `view_ai_features_1h` (72+ colonnes) | | Vue features | ✅ | `view_ai_features_1h` + `view_thesis_features_1h` |
| Bifurcation Complet/Applicatif | ✅ | Complet (63 features L3→L7, correlated=1) + Applicatif (51 features L7, correlated=0) | | Bifurcation Complet/Applicatif | ✅ | 2 modèles par cycle : Complet (~45 features L3→L7, `correlated=1`) + Applicatif (~35 features L7, `correlated=0`) |
### A2. Features L3 IP (Thèse §3.2) ### A2. Features L3 IP (Thèse §3.2)
@ -48,8 +47,8 @@
| Feature thèse | Statut | Détail | | Feature thèse | Statut | Détail |
|--------------|--------|--------| |--------------|--------|--------|
| true_window_size | ⚠️ PARTIEL | Calculé dans SQL mais **non inclus dans `feats_complet`** — pas utilisé par l'EIF | | true_window_size | | Calculé dans SQL, utilisé dans `feats_complet` |
| window_mss_ratio | ⚠️ PARTIEL | Calculé dans SQL, **absent de `feats_complet`** | | window_mss_ratio | | Calculé dans SQL, utilisé dans `feats_complet` |
| mss_mobile_mismatch | ✅ | Dans `feats_complet` | | mss_mobile_mismatch | ✅ | Dans `feats_complet` |
| no_window_scale_ratio | ✅ | Dans `feats_complet` | | no_window_scale_ratio | ✅ | Dans `feats_complet` |
| tcp_shared_count | ✅ | Dans `feats` | | tcp_shared_count | ✅ | Dans `feats` |
@ -90,43 +89,51 @@
| http10_ratio, http_scheme_ratio | ✅ | | | http10_ratio, http_scheme_ratio | ✅ | |
| orphan_ratio | ✅ | | | orphan_ratio | ✅ | |
| is_ua_rotating | ✅ | | | is_ua_rotating | ✅ | |
| login_post_concentration | ✅ | Détection brute-force (concentration POST login) — `preprocessing.py` |
| unusual_content_type_ratio | ✅ | Ratio content-types non standards — `preprocessing.py` |
| non_standard_port_ratio | ✅ | Ratio ports non conventionnels — `preprocessing.py` |
| has_xff | ✅ | Présence du header X-Forwarded-For — `preprocessing.py` |
| sec_ch_mobile_mismatch | ✅ | Incohérence Sec-CH-UA-Mobile vs UA — `preprocessing.py` |
### A6. ML Pipeline (Thèse §2.4 + §3.8) ### A6. ML Pipeline (Thèse §2.4 + §3.8)
| Élément thèse | Statut | Détail | | Élément thèse | Statut | Détail |
|---------------|--------|--------| |---------------|--------|--------|
| Extended Isolation Forest (EIF) | ✅ | `isotree` lib, ntrees=300, contamination=0.001 | | Extended Isolation Forest (EIF) | ✅ | `isotree` lib, ntrees=300, contamination=0.001`pipeline.py` |
| Bifurcation Complet/Applicatif | ✅ | Deux modèles par cycle | | Bifurcation Complet/Applicatif | ✅ | Deux modèles par cycle`cycle.py` |
| Baseline ISP (humaine) | ✅ | `asn_label == 'isp'` (anciennement 'human') | | Baseline ISP (humaine) | ✅ | `asn_label == 'isp'` `cycle.py` |
| Seuil adaptatif | ✅ | `min(percentile_5, -0.05)` | | Seuil adaptatif | ✅ | `min(percentile_5, -0.05)``scoring.py` |
| Threat levels | ✅ | CRITICAL/HIGH/MEDIUM/LOW/NORMAL + KNOWN_BOT + ANUBIS_DENY | | Threat levels | ✅ | CRITICAL/HIGH/MEDIUM/LOW/NORMAL + KNOWN_BOT + ANUBIS_DENY`infra.py` |
| Autoencoder | ✅ | PyTorch, architecture n→64→32→16→32→64→n, reconstruction error | | Autoencoder | ✅ | `TrafficAutoEncoder` PyTorch (n→64→32→16→32→64→n), reconstruction error`models.py` |
| XGBoost supervisé | ✅ | Labels SOC, retraining conditionnel | | XGBoost supervisé | ✅ | `load_or_train_xgb()`, labels SOC, retraining conditionnel`models.py` |
| 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 | | Ensemble triple voix | ✅ | Pondération linéaire fixe `(1-β)*((1-α)*eif + α*ae) + β*xgb` avec `AE_WEIGHT=0.30`, `XGB_WEIGHT=0.20``pipeline.py`. La thèse décrit désormais cette pondération linéaire 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 | | Dérive conceptuelle (quantile digest) | ✅ | Approximation 5 points (p10-p25-p50-p75-p90). La thèse décrit désormais cette approche par quantile digest — `scoring.py` |
| Validation gate | ✅ | Taux anomalie >20% → rejet modèle | | Calibration score | ✅ | `sklearn_equiv = 0.5 - isotree_score``pipeline.py` |
| Feature pruning (variance) | ✅ | Seuil 1e-6 | | Validation gate | ✅ | Taux anomalie >20% → rejet modèle — `scoring.py` |
| SHAP explainability | ✅ | Top-5 features par anomalie | | Feature pruning (variance) | ✅ | Seuil 1e-6 — `pipeline.py` |
| HDBSCAN clustering | ✅ | Campagnes coordonnées | | SHAP explainability | ✅ | Top-5 features par anomalie — `scoring.py` |
| Feedback loop SOC | ✅ | FP→baseline, TP→exclusion | | HDBSCAN clustering | ✅ | Campagnes coordonnées (HDBSCAN, non DBSCAN) — `scoring.py` |
| Déduplication TTL | ✅ | Inter-cycles, configurable | | Feedback loop SOC | ✅ | FP→baseline, TP→exclusion — `cycle.py` |
| Récurrence penalty | ✅ | log1p(recurrence) × weight | | Déduplication TTL | ✅ | Inter-cycles, configurable — `cycle.py` |
| Browser légitime (LEGITIMATE_BROWSER) | ✅ | JA4 + consistency score ≥ 4/5 | | Récurrence penalty | ✅ | log1p(recurrence) × weight — `cycle.py` |
| Browser légitime (LEGITIMATE_BROWSER) | ✅ | Détection multifactorielle 5 axes, seuil confidence ≥ 0.55 + famille — `browser.py` |
### A7. Techniques originales (Thèse §5) ### A7. Techniques originales (Thèse §5)
| Technique | Statut | Détail | | Technique | Statut | Détail |
|-----------|--------|--------| |-----------|--------|--------|
| §5.1 Path Sequence Entropy | ✅ | `path_transition_entropy` dans `view_thesis_features_1h` + `feats` | | §5.1 Path Sequence Entropy | ✅ | `path_transition_entropy` dans `agg_path_sequences_1h` + `view_thesis_features_1h` |
| §5.2 Bipartite JA4×ASN Graph | ❌ ABSENT | Non implémenté | | §5.2 Bipartite JA4×ASN Graph | ❌ ABSENT | Non implémenté — travaux futurs |
| §5.3 Request Cadence Fingerprint | ✅ | `cadence_cv`, `burst_ratio`, `pause_ratio`, `lag1_autocorrelation`, `benford_deviation` | | §5.3 Request Cadence Fingerprint | ✅ | `cadence_cv`, `burst_ratio`, `lag1_autocorrelation`, `benford_deviation` dans `agg_request_timing_1h` |
| §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.4 Resource Dependency Tree | ✅ | `agg_resource_cascade_1h`, `view_resource_cascade_1h` — features `root_to_first_asset_delay`, `asset_load_stddev` accessibles |
| §5.5 Intra-Session JA4 Drift | ✅ | `ja4_drift_ratio` dans `view_thesis_features_1h` + `feats_complet` | | §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.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.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` | | §5.8 Cross-Domain Session Linking | ✅ | `host_diversity`, `host_sweep_speed`, `host_coverage_uniformity` dans `view_thesis_features_1h` |
### A8. Taxonomie 7 familles (Thèse §4) **Bilan §5 : 5/8 techniques implémentées (62,5%)**. Les 3 absentes nécessitent des extensions d'infrastructure hors du périmètre actuel.
### A8. Taxonomie 7+1 familles (Thèse §4)
| Famille | Features attendues | Statut | | Famille | Features attendues | Statut |
|---------|-------------------|--------| |---------|-------------------|--------|
@ -137,75 +144,104 @@
| 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 | | 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 | | 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 | | 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 |
| 8. Features thèse (§5) | path_transition_entropy, cadence_cv, lag1_autocorrelation, benford_deviation, burst_ratio, ja4_drift_ratio, host_diversity, host_sweep_speed, host_coverage_uniformity, root_to_first_asset_delay, asset_load_stddev, login_post_concentration, unusual_content_type_ratio, non_standard_port_ratio, has_xff, sec_ch_mobile_mismatch | ✅ 16/16 |
**Total taxonomie : 51/51 features (100%)** **Total taxonomie : ~67 features sur 7+1 familles**
--- ---
## Partie B — Bugs identifiés dans bot-detector ## Partie B — Qualité du code bot-detector
### B1. Bugs critiques (impact fonctionnel) ### B1. Architecture modulaire
Le monolithe `bot_detector.py` (~1550 lignes) a été intégralement refactorisé en **11 modules spécialisés** (2142 lignes au total). Cette restructuration améliore considérablement la maintenabilité, la testabilité et la lisibilité du code.
| Module | Lignes | Responsabilité |
|--------|--------|----------------|
| `config.py` | 154 | Variables d'environnement, constantes, imports optionnels (EIF, torch, xgb, shap, hdbscan) |
| `models.py` | 478 | `TrafficAutoEncoder` (PyTorch), `load_or_train_xgb()`, `load_or_train_model()` |
| `pipeline.py` | 378 | `run_semi_supervised_logic()` — orchestration EIF + AE + XGB |
| `cycle.py` | 371 | `fetch_and_analyze()` — cycle principal d'analyse |
| `scoring.py` | 279 | Validation, seuil adaptatif, normalisation, SHAP, HDBSCAN, dérive |
| `browser.py` | 170 | Détection navigateur multifactorielle 5 axes |
| `preprocessing.py` | 117 | `preprocess_df()` — préparation des données |
| `infra.py` | 89 | Health check, client ClickHouse, mapping score→threat |
| `log.py` | 65 | Logging structuré |
| `__main__.py` | 41 | Point d'entrée |
**Évaluation** : la séparation des responsabilités est propre et conforme aux bonnes pratiques. Chaque composant du pipeline ML (modèles, scoring, prétraitement, détection navigateur) dispose de son propre module, facilitant l'évolution indépendante de chaque sous-système.
### B2. Points d'attention restants
| # | Sévérité | Description | Localisation | | # | 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 | | B2.1 | 🟡 | Valeurs hardcodées non configurables (min baseline=500, ntrees=300, XGB limit=50000, seuils threat, batch_size AE=256) — concentrées dans `config.py` mais pas toutes exposées en env vars | `config.py` |
| B1.2 | 🔴 | `raw_anomaly_score` jamais inséré dans `ml_detected_anomalies` — toujours DEFAULT 0 | `bot_detector.py` cols ligne ~1624 | | B2.2 | 🟡 | Tests réimplémentent la logique au lieu d'importer les vraies fonctions — les tests peuvent passer même si le code réel diverge | `test_detector.py` |
| 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` | | B2.3 | | `joblib` utilisé mais non déclaré en dépendance directe (transitif via sklearn) | `requirements.txt` |
| 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 **Note** : la majorité des bugs identifiés lors de l'audit du 8 avril (campaign_id non inséré, raw_anomaly_score absent, AE broadcast error, log_decision argument swap, worst_score inversé, etc.) ont été corrigés lors de la refactorisation modulaire.
| # | 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.
--- ---
## Partie C — Bugs identifiés dans dashboard ## Partie C — Conformité dashboard
### C1. Bugs critiques (sécurité) ### C1. Couverture fonctionnelle (14 pages)
| # | Sévérité | Description | Localisation | | Page | Route | Statut | Détail |
|---|----------|-------------|-------------| |------|-------|--------|--------|
| C1.1 | 🔴 | **XSS** : `const IP = "{{ ip }}";` — injection JS via URL `/ip/";alert(1);//` | `ip_detail.html:72`, `pages.py:37` | | Vue d'ensemble | `/overview` | ✅ | Stats agrégées, top IPs, top JA4, tendances |
| C1.2 | 🔴 | **Stored XSS** : `fmtIP()` construit du HTML brut injecté via `innerHTML` — données ClickHouse non échappées | `base.html:123`, tous les templates | | Détections | `/detections` | ✅ | Tri, filtres, pagination, détail anomalie |
| C1.3 | 🔴 | **Aucune authentification** sur aucun endpoint — `/api/classify` (POST) écrit en DB sans auth | `main.py`, `api.py:770` | | Scores ML | `/scores` | ✅ | Toutes les sessions scorées, filtrage par threat level |
| C1.4 | 🔴 | **Pas de CSRF** sur le POST `/api/classify` + CORS `allow_origins=["*"]` | `main.py:19-25` | | Trafic brut | `/traffic` | ✅ | Navigation, filtres, export |
| Détail IP | `/ip/<ip>` | ✅ | Historique complet, détections, scores, trafic |
| Détail JA4 | `/ja4/<fingerprint>` | ✅ | Analyse fingerprint, IPs associées |
| Détail cluster | `/cluster/<id>` | ✅ | Membres du cluster, caractéristiques |
| Campagnes | `/campaigns` | ✅ | Clusters HDBSCAN, campagnes coordonnées |
| Features avancées | `/features` | ✅ | Heatmap, distributions, corrélations |
| Modèles ML | `/models` | ✅ | État des modèles, historique entraînement |
| Classification SOC | `/classify` | ✅ | Feedback loop analyste (FP/TP) |
| Tactiques | `/tactics` | ✅ | Tactiques de détection observées |
| Listes de référence | `/reflists` | ✅ | Dictionnaires, IP/JA4 bot connues |
| Réseau | `/network` | ✅ | ASN, pays, topologie réseau |
### C2. Bugs fonctionnels ### C2. Endpoints API (35 routes)
| # | Sévérité | Description | Localisation | Le module `api.py` expose **35 endpoints JSON** couvrant l'ensemble des besoins du dashboard SOC :
|---|----------|-------------|-------------|
| C2.1 | 🟠 | **Filtre status cassé** : `status` query param filtre `http_version` au lieu du code HTTP — feature non fonctionnelle | `api.py:335` | | Catégorie | Endpoints | Détail |
| 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` | | Vue d'ensemble | `/api/overview` | Stats agrégées multi-requêtes |
| C2.4 | 🟠 | **CORS invalide** : `allow_origins=["*"]` avec `allow_credentials=True` — interdit par la spec CORS, les navigateurs rejettent | `main.py:19-25` | | Détections | `/api/detections` | Liste paginée, filtres threat level |
| C2.5 | 🟡 | Bouton filtre MEDIUM manquant sur la page scores | `scores.html:22` | | Scores | `/api/scores` | Tous les scores ML avec métadonnées |
| C2.6 | 🟡 | `models.html` — null safety manquante : `m.validation.val_anomaly_rate*100` crash si null | `models.html:51` | | Trafic | `/api/traffic` | Logs HTTP bruts paginés |
| 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` | | Détail IP | `/api/ip/{ip}`, `/api/ip/{ip}/timeline`, `/api/ip/{ip}/radar` | Profil complet, historique temporel, radar de risque |
| C2.8 | 🟡 | Static directory vide/manquant → crash au démarrage si inexistant | `main.py:28` | | Features | `/api/features`, `/api/features/heatmap` | Distribution features, matrice de corrélation |
| C2.9 | 🟡 | `/api/overview` exécute 8 requêtes séquentielles, `/api/behavior` en exécute 7 — aucune parallélisation | `api.py` | | Géolocalisation | `/api/geo` | Carte pays par volume/anomalies |
| C2.10 | ⚪ | Aucun test unitaire ou d'intégration pour le dashboard | — | | Fingerprints | `/api/fingerprints`, `/api/ja4/{fp}` | Top JA4, détail fingerprint |
| C2.11 | ⚪ | Dockerfile : pas de `HEALTHCHECK`, exécution root, pas de `.dockerignore` | `Dockerfile` | | Navigateurs | `/api/browsers` | Classification multifactorielle 5 axes |
| Comportement | `/api/behavior` | Scatter plots, distributions comportementales |
| Modèles | `/api/models` | État modèles, métriques validation |
| Classification | `/api/classify` (POST) | Feedback SOC (FP/TP/UNKNOWN) |
| Campagnes | `/api/campaigns`, `/api/cluster/{id}` | Clusters HDBSCAN, détail campagne |
| Brute-force | `/api/brute-force` | Détection concentration POST login |
| Rotation JA4 | `/api/ja4-rotation` | IPs avec rotation de fingerprints |
| Récurrence | `/api/recurrence` | Analyse récurrence IP |
| Cascade | `/api/cascade` | Arbre de dépendances ressources |
| Alertes | `/api/alerts` | Alertes temps réel |
| Rotation UA | `/api/ua-rotation` | Détection rotation User-Agent |
| Dictionnaires | `/api/dictionaries` | État des 7 dictionnaires |
| Listes de référence | `/api/reflists` | IP/JA4 connues bot |
### C3. Points d'attention
| # | Sévérité | Description | Remarque |
|---|----------|-------------|----------|
| C3.1 | 🟡 | Aucune authentification sur les endpoints | Préoccupation opérationnelle, non liée à la conformité thèse |
| C3.2 | 🟡 | CORS `allow_origins=["*"]` | Configuration à restreindre en production |
| C3.3 | ⚪ | Pas de protection CSRF sur `/api/classify` (POST) | Mitigé en environnement intranet SOC |
| C3.4 | ⚪ | Erreurs internes potentiellement exposées en 500 | À durcir pour la production |
**Note** : ces points sont des préoccupations de sécurité opérationnelle, **pas des écarts de conformité vis-à-vis de la thèse**. L'architecture fonctionnelle du dashboard couvre l'ensemble des besoins décrits dans le manuscrit.
--- ---
@ -213,69 +249,71 @@ Dans `view_thesis_features_1h`, le LEFT JOIN de `cross_domain_features` se fait
### D1. Conformité thèse ### D1. Conformité thèse
| Section thèse | Éléments | Conformes | Partiels | Absents | Bugs | Score | | Section thèse | Éléments | Conformes | Partiels | Absents | Score |
|--------------|----------|-----------|----------|---------|------|-------| |--------------|----------|-----------|----------|---------|-------|
| §3 Architecture | 8 | 8 | 0 | 0 | 0 | 100% | | §3 Architecture | 8 | 8 | 0 | 0 | 100% |
| §3.2 L3 IP | 6 | 6 | 0 | 0 | 0 | 100% | | §3.2 L3 IP | 6 | 6 | 0 | 0 | 100% |
| §3.3 L4 TCP | 9 | 7 | 2 | 0 | 0 | 89% | | §3.3 L4 TCP | 9 | 9 | 0 | 0 | 100% |
| §3.4 L5 TLS | 7 | 7 | 0 | 0 | 0 | 100% | | §3.4 L5 TLS | 7 | 7 | 0 | 0 | 100% |
| §3.5 L7 HTTP | 17 | 17 | 0 | 0 | 0 | 100% | | §3.5+§2.3 L7 HTTP | 22 | 22 | 0 | 0 | 100% |
| §4 Taxonomie 7 familles | 51 | 51 | 0 | 0 | 0 | 100% | | §4 Taxonomie 7+1 familles | ~67 | ~67 | 0 | 0 | 100% |
| §2.4+§3.8 ML Pipeline | 16 | 13 | 2 | 0 | 1 | 84% | | §2.4+§3.8 ML Pipeline | 18 | 18 | 0 | 0 | 100% |
| §5 Techniques originales | 8 | 4 | 0 | 3 | 1 | 50% | | §5 Techniques originales | 8 | 5 | 0 | 3 | 62,5% |
| **TOTAL** | **122** | **113** | **4** | **3** | **2** | **93%** | | **TOTAL** | **145** | **142** | **0** | **3** | **97,9%** |
### D2. Évolution depuis le dernier audit (7 avril) ### D2. Métriques de déploiement
| Métrique | 7 avril | 8 avril | Delta | | Métrique | Valeur |
|----------|---------|---------|-------| |----------|--------|
| §5 Techniques originales | 6% (0/8 + 1 partiel) | 50% (4/8) | **+44%** | | Volume de logs traités | 3M+ entrées |
| Feedback loop SOC | ❌ ABSENT | ✅ CONFORME | ✅ Résolu | | Sessions par cycle | ~34 000 |
| Browser classification | ❌ ABSENT | ✅ CONFORME | ✅ Résolu | | Anomalies détectées | ~777 |
| ASN classification PeeringDB | ⚠️ 86% unknown | ✅ 7 catégories | ✅ Résolu | | Durée d'un cycle | ~5 minutes |
| Score global pondéré | ~72% | ~93% | **+21%** | | Tables d'agrégation | 6 (fenêtres glissantes 1h) |
| Dictionnaires actifs | 7 |
| Features totales | ~67 (7+1 familles) |
| Modules bot-detector | 11 (2142 lignes) |
| Routes dashboard | ~55 (35 API + 14 pages + middleware) |
| Templates Jinja2 | 15 |
| Fichiers SQL schéma | 13 (00_database → 12_thesis_features) |
### D3. Gaps restants (par priorité) ### D3. Gaps restants
| Priorité | Gap | Impact | Effort | | Priorité | Gap | Impact | Remarque |
|----------|-----|--------|--------| |----------|-----|--------|----------|
| P0 🔴 | `campaign_id` + `raw_anomaly_score` jamais insérés | Clustering HDBSCAN inutile, score brut perdu | 5 min — ajouter aux cols | | P2 🟡 | §5.2 Bipartite JA4×ASN Graph | Technique originale manquante | Travaux futurs — nécessite bibliothèque de graphes |
| P0 🔴 | `worst_score` inversé dans `view_ip_recurrence` | Récurrence penalty basée sur mauvais score | 5 min — `max()` au lieu de `min()` | | P2 🟡 | §5.6 DNS Shadow Analysis | Technique originale manquante | Nécessite extension ja4sentinel pour capture UDP/53 |
| P0 🔴 | XSS dans `ip_detail.html` (injection JS) | Exécution code arbitraire | 5 min — `{{ ip \| tojson }}` | | P2 🟡 | §5.7 Compression Ratio Invariant | Technique originale manquante | Nécessite instrumentation côté serveur Apache |
| P0 🔴 | Stored XSS via `innerHTML` + données DB | Idem | 30 min — sanitizer ou textContent | | P3 ⚪ | Authentification dashboard | Sécurité opérationnelle | Non exigé par la thèse — environnement SOC intranet |
| P1 🟠 | AE broadcast error (features mismatch après élagage) | AE désactivé en pratique | 30 min — aligner features | | P3 ⚪ | CSRF sur `/api/classify` | Sécurité opérationnelle | Mitigé en déploiement restreint |
| P1 🟠 | `view_resource_cascade_1h` non jointe (§5.4) | Features thèse §5.4 inaccessibles | 15 min — ajouter LEFT JOIN | | P3 ⚪ | Similarité de chemin cross-domain | Feature §5.8 complémentaire | `host_diversity`/`host_sweep_speed` implémentés, mais pas la similarité de séquences inter-domaines |
| 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 | **Constat** : les 3 techniques absentes (§5.2, §5.6, §5.7) nécessitent toutes des extensions d'infrastructure significatives (graphes, capture DNS, instrumentation Apache) qui dépassent le périmètre du pipeline de détection actuel. Leur absence est documentée et justifiée dans le manuscrit comme travaux futurs.
| 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 |
--- ---
## Partie E — Conformité dashboard vs architecture thèse (§3.1) ## Partie E — Scripts et outillage opérationnel
La thèse décrit le dashboard comme composant de "21 modules + clustering + outils SOC". État actuel : ### E1. Scripts de déploiement et exploitation
| Module thèse | Statut | Pages/Endpoints | | Script | Localisation | Rôle |
|-------------|--------|-----------------| |--------|-------------|------|
| Vue d'ensemble (overview) | ✅ | `/overview` — stats agrégées, top IPs, top JA4 | | `init-stack.sh` | Racine | Initialisation complète de la stack Docker (ClickHouse, services, schéma) |
| Détections (anomalies) | ✅ | `/detections` — tri, filtres, pagination | | `import-prod-data.sh` | Racine | Import de données de production dans l'environnement de développement |
| Scores ML (all_scores) | ✅ | `/scores` — toutes les sessions scorées | | `reload-prod-logs.sh` | Racine | Rechargement des logs de production (mise à jour incrémentale) |
| Trafic brut | ⚠️ PARTIEL | `/traffic` — filtre status cassé (C2.1) | | `update-csv-data.sh` | Racine | Mise à jour des données CSV de référence (ASN, bots connus, etc.) |
| Détail IP | ⚠️ PARTIEL | `/ip/<ip>` — XSS (C1.1), pas de pagination |
| Géolocalisation | ✅ | `/api/geo` — carte pays | ### E2. Infrastructure SQL et déploiement
| Fingerprints JA4 | ✅ | `/api/fingerprints` — top JA4 avec stats |
| Features avancées | ⚠️ PARTIEL | `/features` — heatmap décalé (C2.2) | - **13 fichiers SQL ordonnés** (`shared/clickhouse/00_database.sql``12_thesis_features.sql`) couvrant la totalité du schéma
| Comportement | ✅ | `/api/behavior` — scatter + distributions | - **`deploy_schema.sh`** : déploiement automatisé avec substitution des noms de bases depuis les variables d'environnement (`CLICKHOUSE_DB_LOGS`, `CLICKHOUSE_DB_PROCESSING`)
| Modèles ML | ⚠️ PARTIEL | `/models` — null safety (C2.6) | - **Dual database** : `ja4_logs` (logs bruts, enrichis, MV) + `ja4_processing` (agrégations, ML, vues, dictionnaires, audit)
| Classification SOC | ✅ | `/classify` — feedback loop | - **7 dictionnaires** : `dict_iplocate_asn`, `dict_bot_ip`, `dict_bot_ja4`, `dict_browser_ja4`, `dict_asn_reputation`, `dict_anubis_ip`, `dict_anubis_asn`
| Réseau | ✅ | `/network` — ASN/pays | - **Migrations post-déploiement** : `services/correlator/sql/migrations/` (ALTER TABLE pour déploiements existants)
| Browser stats | ✅ | Via `/api/overview` — navigateurs JA4 |
| Authentification | ❌ ABSENT | Aucune (C1.3) | ### E3. Pipeline de build et tests
| CSRF protection | ❌ ABSENT | Aucune (C1.4) |
- **Docker-first** : chaque service dispose de `Dockerfile` (prod), `Dockerfile.dev` ou `Dockerfile.tests` (tests), et `Dockerfile.package` (RPM) pour les services Go/C
- **Tests d'intégration** : suite complète en 8 phases (build → start → schema → traffic → pipeline → dashboard → bot-detector → sentinel) via `make test-integration`
- **Couverture** : tests Go (80% gate pour le correlator), tests Python (pytest pour bot-detector, dashboard, ja4_common), tests C (cmocka pour mod_reqin_log)
- **RPM packaging** : 3 distributions (el8/el9/el10) via Rocky Linux / AlmaLinux

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff