Replace the LogisticRegression meta-learner with a PyTorch MetaFusionMLP (Linear(3,16)->BN->ReLU->Dropout->Linear(16,1)->Sigmoid) for non-linear fusion of EIF, NF, and XGBoost scores. Replace KS-test + quantile digest drift detection with ADWIN (adaptive sliding window, Hoeffding bound). Replace weekly XGBoost batch retraining with River HoeffdingAdaptiveTree for incremental online learning (learn_one per cycle). Update all thesis documentation sections (2.4.2c, 2.4.3, 3.8, discussion, conclusion). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
26 KiB
Bot Detector IA — Axes d'amélioration
Suivi d'implémentation — mis à jour le 2026-04-13 | Architecture modulaire (16 modules)
Résumé des axes proposés — État d'implémentation
| # | Axe | Statut | Implémentation |
|---|---|---|---|
| A1 | Détection de dérive conceptuelle | ✅ IMPLÉMENTÉ | scoring.py : _compute_drift_score() + fallback z-score |
| A2 | Seuil adaptatif par percentile | ✅ IMPLÉMENTÉ | scoring.py : compute_adaptive_threshold() |
| A3 | Analyse multi-fenêtres temporelles | ✅ IMPLÉMENTÉ | cycle.py : ENABLE_MULTIWINDOW + Complet_24h/Applicatif_24h |
| A4 | Explainabilité par SHAP | ✅ IMPLÉMENTÉ | scoring.py : _compute_shap_top_features(), top-5 |
| A5 | Déduplication avec TTL inter-cycles | ✅ IMPLÉMENTÉ | cycle.py : _filter_recent_detections(), DEDUP_TTL_MIN=60 |
| A6 | Pondération par récurrence dans le score | ✅ IMPLÉMENTÉ | pipeline.py : raw -= log1p(count) * RECURRENCE_WEIGHT |
| A7 | Validation de complétude des features | ✅ IMPLÉMENTÉ | scoring.py : validate_features(), MIN_VALID_FEATURE_RATIO=0.50 |
| A8 | Clustering comportemental des anomalies | ✅ IMPLÉMENTÉ | scoring.py : HDBSCAN + escalade campagne dans pipeline.py |
| A9 | Métriques Prometheus / health check enrichi | ❌ À FAIRE | Health check binaire uniquement (infra.py : 200/503) |
| A10 | Normalisation des scores entre modèles | ✅ IMPLÉMENTÉ | scoring.py : normalize_scores() min-max [0, 1] |
A1 — Détection de dérive conceptuelle
✅ IMPLÉMENTÉ (ADWIN)
Module : scoring.py — classe ADWINDriftMonitor (remplace _compute_drift_score)
Différences avec la proposition initiale :
| Proposition | Implémentation |
|---|---|
| KS-test + quantile digest | ADWIN (fenêtre glissante adaptative, borne de Hoeffding) |
Seuil par p_value < 0.05 |
Borne de Hoeffding automatique (delta = 0.002) |
DRIFT_THRESHOLD (30%) |
✅ Identique : DRIFT_THRESHOLD = 0.30 (fraction de features en dérive) |
Sauvegarde dans .meta.json |
ADWIN stateful — pas de sauvegarde nécessaire (fenêtre adaptative) |
Événement DRIFT_DETECTED |
✅ Journalisé avec la liste des features dérivées |
Appelé depuis : models.py → load_or_train_model(), avant la décision de chargement vs retrain.
Problème
L'Isolation Forest est entraîné sur la baseline humaine courante. Si le profil du trafic légitime évolue graduellement (nouveau navigateur populaire, changement de comportement utilisateur, migration réseau), le modèle vieilli peut :
- Générer des faux positifs sur du trafic humain nouvellement apparu
- Rater des faux négatifs si les bots imitent les anciens patterns
Références
- Gama et al. (2014) — A Survey on Concept Drift Adaptation
- Rabanser et al. (2019) — Failing Loudly: An Empirical Study of Methods for Detecting Dataset Shift
A2 — Seuil adaptatif par percentile
✅ IMPLÉMENTÉ
Module : scoring.py — fonction compute_adaptive_threshold()
Implémentation conforme à la proposition :
neg_scores = scores[scores < 0]
adaptive = np.percentile(neg_scores, ANOMALY_PERCENTILE) # défaut : 5
effective_threshold = min(adaptive, ANOMALY_THRESHOLD) # garde-fou : -0.05
| Proposition | Implémentation |
|---|---|
ANOMALY_PERCENTILE (0–20, défaut 5) |
✅ config.py : ANOMALY_PERCENTILE = 5 |
| Seuil statique en garde-fou | ✅ ANOMALY_THRESHOLD = -0.05 |
Log du seuil effectif dans ANOMALY |
✅ Journalisé dans les événements |
Appelé depuis : pipeline.py ligne 144, sur les scores bruts EIF uniquement.
A3 — Analyse multi-fenêtres temporelles
✅ IMPLÉMENTÉ
Module : cycle.py — dans fetch_and_analyze(), lignes 257–275
Implémentation :
| Proposition | Implémentation |
|---|---|
| Vue 24h dans ClickHouse | ✅ MULTIWINDOW_VIEW = 'view_ai_features_24h' (configurable) |
| Deux modèles supplémentaires | ✅ Complet_24h et Applicatif_24h |
| Combinaison AND logique | Implémenté en OR logique : une IP est flaggée si anomalie dans ≥ 1 fenêtre |
| Score le plus bas conservé | ✅ En cas de doublon, le score le plus bas (le plus anormal) est conservé |
| Activation par feature flag | ✅ ENABLE_MULTIWINDOW = false par défaut |
Note : La proposition originale suggérait un AND logique (anomalie dans les deux fenêtres). L'implémentation utilise un OR pour maximiser la couverture, avec déduplication par score minimal.
A4 — Explainabilité par SHAP
✅ IMPLÉMENTÉ
Module : scoring.py — fonction _compute_shap_top_features()
| Proposition | Implémentation |
|---|---|
TreeExplainer (sklearn IF) |
✅ Pour sklearn : shap.TreeExplainer |
| Top-5 features les plus contributives | ✅ Top-5 features avec valeurs SHAP |
ENABLE_SHAP=true/false |
✅ config.py : ENABLE_SHAP = true (ET SHAP_AVAILABLE) |
| SHAP uniquement sur les anomalies | ✅ Calculé uniquement pour les IPs flaggées |
Enrichissement du champ reason |
✅ Via _build_reason() — SHAP intégré dans la raison textuelle |
Ajout par rapport à la proposition : Pour isotree (Extended IF), SHAP utilise
PermutationExplainer au lieu de TreeExplainer (isotree n'est pas nativement
supporté par TreeSHAP).
Appelé depuis : pipeline.py lignes 298–303, après l'extraction des anomalies.
Références
- Lundberg & Lee (2017) — A Unified Approach to Interpreting Model Predictions
A5 — Déduplication avec TTL inter-cycles
✅ IMPLÉMENTÉ
Module : cycle.py — fonction _filter_recent_detections()
| Proposition | Implémentation |
|---|---|
DEDUP_TTL_MIN (défaut 60 min) |
✅ config.py : DEDUP_TTL_MIN = 60 |
| Requête ClickHouse pour les IPs récentes | ✅ Interroge ml_detected_anomalies dans les dernières DEDUP_TTL_MIN minutes |
| Variante : réinsertion si dégradation ≥ 0.05 | ✅ Réinsertion uniquement si le score s'est dégradé de ≥ 0.05 points |
DEDUP_TTL_MIN=0 pour désactiver |
✅ Conforme |
Déduplication intra-cycle (drop_duplicates) |
✅ cycle.py ligne 302 : drop_duplicates(subset=['src_ip'], keep='first') |
A6 — Pondération par récurrence dans le score
✅ IMPLÉMENTÉ
Module : pipeline.py — lignes 148–151
| Proposition | Implémentation |
|---|---|
RECURRENCE_WEIGHT = 0.005 |
✅ config.py : RECURRENCE_WEIGHT = 0.005 |
adjusted = score - log1p(recurrence) * weight |
✅ raw_anomaly_score -= log1p(recurrence_count) * RECURRENCE_WEIGHT |
| Récurrence chargée depuis ClickHouse | ✅ view_ip_recurrence dans cycle.py ligne 215 |
| Stockage séparé raw_score / adjusted_score | Le score ajusté remplace raw_anomaly_score (pas de stockage séparé) |
A7 — Validation de complétude des features
✅ IMPLÉMENTÉ
Module : scoring.py — fonction validate_features()
| Proposition | Implémentation |
|---|---|
| Détection des features absentes | ✅ Features manquantes du DataFrame |
| Détection des features constantes (std=0) | ✅ Features à std=0 exclues |
MIN_VALID_FEATURE_RATIO (défaut 0.8) |
Implémenté à 0.50 (seuil moins strict) |
Événement FEATURE_WARNING |
✅ Journalisé dans le JSONL |
SKIPPED_INVALID_FEATURES si ratio insuffisant |
✅ Retourne None → cycle ignoré |
Ajouts par rapport à la proposition :
- Détection des features entièrement à zéro (pipeline non alimenté) en plus des features constantes.
- Exclusions structurelles par modèle (
STRUCTURAL_EXCLUDED_FEATURESdansconfig.py) : le modèle Applicatif exclut automatiquement 15 features TCP/TLS non disponibles sans corrélation.
A8 — Clustering comportemental des anomalies
✅ IMPLÉMENTÉ
Module : scoring.py — fonction _cluster_anomalies() + pipeline.py pour l'escalade
| Proposition | Implémentation |
|---|---|
| DBSCAN (eps=0.5, min_samples=3) | Utilisé en fallback. Algorithme principal : HDBSCAN |
campaign_id dans les événements |
✅ Journalisé dans les événements ANOMALY et inséré dans ml_detected_anomalies |
eps et min_samples configurables |
✅ CLUSTERING_MIN_SAMPLES = 3, ENABLE_CLUSTERING = true |
| Activation conditionnelle | ✅ ENABLE_CLUSTERING (feature flag) |
Améliorations par rapport à la proposition :
-
HDBSCAN au lieu de DBSCAN : Utilise
HDBSCAN(min_cluster_size=3, min_samples=2, cluster_selection_method='eom')via import optionnelhdbscan. Fallback DBSCAN sihdbscannon installé. -
Clustering dans l'espace latent : Si un modèle Autoencoder est disponible, le clustering opère dans l'espace latent (dimension 16) plutôt que sur les features brutes — meilleure séparation des clusters.
-
Escalade de campagne (
pipeline.pylignes 311–324) : Les IPs d'un cluster ≥ 5 membres voient leur threat level escaladé deHIGH→CRITICAL.
Références
- Ester et al. (1996) — A Density-Based Algorithm for Discovering Clusters in Large Spatial Databases
- Campello et al. (2013) — Density-Based Clustering Based on Hierarchical Density Estimates (HDBSCAN)
A9 — Métriques Prometheus / health check enrichi
❌ À FAIRE
État actuel : Le health check est un serveur HTTP binaire dans infra.py
(200 OK / 503 DEGRADED). Aucun endpoint /metrics n'est exposé.
Ce qui manque :
- Endpoint
/metricsau format Prometheus text - Métriques : durée du cycle, nombre d'anomalies par modèle, âge du modèle, taille de la baseline, score de dérive
- Intégration Grafana/Alertmanager
Prérequis : Ajouter prometheus_client aux dépendances ou implémenter le
format texte manuellement sur le HTTPServer existant.
Note : La priorité est faible car les métriques clés sont déjà disponibles via
les événements CYCLE_END dans le JSONL et les tables ClickHouse (ml_all_scores).
Proposition originale
Exposer un endpoint /metrics sur le même port que le health check :
botdetector_cycle_duration_seconds 12.4
botdetector_anomalies_total{model="Complet"} 3
botdetector_model_age_hours{model="Applicatif"} 0.91
botdetector_human_baseline_size{model="Applicatif"} 1725
A10 — Normalisation des scores entre modèles
✅ IMPLÉMENTÉ
Module : scoring.py — fonction normalize_scores()
| Proposition | Implémentation |
|---|---|
| Min-max sur les scores < 0 | ✅ Normalisation min-max des scores négatifs |
| Intervalle [-1, 0] | Intervalle [0, 1] où 1 = le plus anormal |
| Threat levels sur score normalisé | Les threat levels sont toujours calculés sur le score brut IF (score_to_threat_level() dans infra.py) |
| Déduplication sur score normalisé | La déduplication utilise le score brut ajusté (avec pénalité de récurrence) |
Note : Le choix de conserver les threat levels sur le score brut (plutôt que
normalisé) assure la stabilité des seuils de classification. Le score normalisé
est utilisé pour le score final combiné (EIF+AE+XGB) et l'insertion dans
ml_all_scores.
Notes d'implémentation générales
- Compatibilité : toute amélioration doit rester rétrocompatible avec le schéma
ml_detected_anomaliesexistant (ajout de colonnes optionnelles uniquement) - Architecture modulaire : le code est réparti en 16 modules (voir
DOCUMENTATION.md§1.1), chaque amélioration touche un ou deux modules spécifiques - Tests : 36 tests auto-contenus dans
tests/test_detector.py, exécutables viamake test-bot-detector - Feature flags : les fonctionnalités sont activables via variables d'environnement (
ENABLE_SHAP,ENABLE_CLUSTERING,ENABLE_MULTIWINDOW,ENABLE_FEEDBACK) - Imports optionnels :
isotree,torch,xgboost,shap,hdbscansont tous optionnels avec fallbacks (config.py)
Nouvelles dimensions de features — Propositions B
Propositions de features supplémentaires pour l'ensemble ML, validées sur les données réelles de
ja4_processing. Chaque proposition indique la force du signal observée en base, la source de données, la formule de calcul et les références scientifiques.
Résumé des signaux — État d'implémentation
| # | Feature | Statut | Modèle | Implémentation |
|---|---|---|---|---|
| B1 | ja3_diversity_ratio |
✅ IMPLÉMENTÉ | Complet | FEATURES_COMPLET dans preprocessing.py ligne 56 |
| B2 | syn_timing_cv |
✅ IMPLÉMENTÉ | Complet | FEATURES_COMPLET dans preprocessing.py ligne 56 |
| B3 | tls12_ratio |
✅ IMPLÉMENTÉ | Complet | FEATURES_COMPLET dans preprocessing.py ligne 56 |
| B4 | head_ratio |
✅ IMPLÉMENTÉ | Les deux | FEATURES dans preprocessing.py ligne 30 |
| B5 | sec_fetch_absence_rate |
✅ IMPLÉMENTÉ | Les deux | FEATURES dans preprocessing.py ligne 30 |
| B6 | generic_accept_ratio |
✅ IMPLÉMENTÉ | Les deux | FEATURES dans preprocessing.py ligne 30 |
| B7 | http10_ratio |
✅ IMPLÉMENTÉ | Les deux | FEATURES dans preprocessing.py ligne 30 |
| B8 | ip_df_variance |
✅ IMPLÉMENTÉ | Complet | FEATURES_COMPLET dans preprocessing.py ligne 56 |
| B9 | IP DF-bit consistency | 🔄 PARTIEL | Complet | Couvert par B8 (ip_df_variance), pas de feature séparée |
| B10 | JA4 concentration intra-ASN | ✅ IMPLÉMENTÉ (préexistant) | Les deux | ja4_asn_concentration dans FEATURES — existait avant les propositions B |
B1 — JA3/JA4 Diversity Ratio (rotation de fingerprint TLS)
✅ IMPLÉMENTÉ
Feature : ja3_diversity_ratio — dans FEATURES_COMPLET (modèle Complet uniquement).
Exclusion structurelle : Exclue du modèle Applicatif via STRUCTURAL_EXCLUDED_FEATURES
dans config.py, car le JA3 n'est disponible que pour le trafic corrélé (L4/TLS).
Détails d'implémentation :
- La vue ClickHouse
view_ai_features_1hcalculeuniqMerge(uniq_ja3) / greatest(uniq_ja4, 1) - Le MV
mv_agg_host_ip_ja4_1hagrègeuniqState(ja3)depuishttp_logs
Observation originale
185.177.72.60 → 1619 JA3 distincts / 2 JA4 → ratio 809.5
194.187.171.160 → 153 JA3 distincts / 2 JA4 → ratio 76.5
Le JA4 reste stable (il encode le type de client TLS + ALPN) mais le JA3 varie massivement. C'est la signature d'un bot qui randomise les extensions TLS pour contourner la détection par fingerprint.
Références
- Siby et al. (2020) — Encrypted DNS → Privacy? A Traffic Analysis Perspective
- Anderson & McGrew (2016) — Machine Learning for Encrypted Malware Traffic Classification
- Husák et al. (2022) — TLS fingerprinting for bot detection
B2 — SYN-to-ClientHello Timing Regularity
✅ IMPLÉMENTÉ
Feature : syn_timing_cv — dans FEATURES_COMPLET (modèle Complet uniquement).
Implémentation : Coefficient de variation (std/mean) du timing SYN→ClientHello,
calculé dans la vue ClickHouse : sqrt(tcp_jitter_variance) / greatest(avg_syn_ms, 1).
Observation originale
88.202.237.59 : 45 connexions, avg=22ms, std=0.00ms → timing robotique parfait
386/3222 IPs analysées (12%) ont une variance=0
Références
- Zeber et al. (2020) — The Measurement of Web Timing
- Stevanovic & Pedersen (2015) — Detecting Bots Using Multi-level Traffic Analysis
B3 — TLS 1.2 Exclusive Ratio
✅ IMPLÉMENTÉ
Feature : tls12_ratio — dans FEATURES_COMPLET (modèle Complet uniquement).
Utilisation double : En plus d'être une feature ML, tls12_ratio est utilisée
par l'axe 5 (TLS/TCP Coherence) de la détection navigateur dans browser.py
(condition tls12_ratio < 0.1 pour un score positif).
Observation originale
95.217.144.244 : 360/360 requêtes en TLS 1.2 (jamais TLS 1.3)
136 IPs utilisent exclusivement TLS 1.2 sur 3259 analysées (4.2%)
Références
- Kotzias et al. (2018) — Coming of Age: A Longitudinal Study of TLS Deployment
- Cloudflare Radar 2024 — TLS 1.3 = 95%+ du trafic web mondial
B4 — HEAD Method Ratio
✅ IMPLÉMENTÉ
Feature : head_ratio — dans FEATURES (les deux modèles).
Commentaire dans le code : # B4-B7 : features L7 pures (preprocessing.py ligne 29).
Observation originale
34.140.199.84 : 11/12 requêtes HEAD (91.7%) → Google Cloud uptime checker
67/3335 IPs ont >50% de requêtes HEAD
Références
- Barracuda Networks (2023) — Bot Traffic Report
- OWASP Automated Threat Handbook — OAT-011: Scraping, OAT-018: Credential Stuffing
B5 — Sec-Fetch Absence Rate
✅ IMPLÉMENTÉ
Feature : sec_fetch_absence_rate — dans FEATURES (les deux modèles).
Utilisation double : Également utilisée par l'axe 3 (HTTP Modern) de la
détection navigateur dans browser.py (condition sec_fetch_absence_rate < 0.3
pour un score positif, poids 0.25).
Observation originale
Les headers Sec-Fetch-* sont injectés automatiquement par les navigateurs modernes
(Chrome 76+, Firefox 90+). Leur absence signale un client non-navigateur.
Références
- West & Loshbough (2019) — Fetch Metadata Request Headers (W3C Spec)
- Invernizzi et al. (2016) — CLOAK of Visibility
B6 — Accept Header Entropy
✅ IMPLÉMENTÉ
Feature : generic_accept_ratio — dans FEATURES (les deux modèles).
Note : La proposition originale suggérait une entropie du header Accept. L'implémentation utilise l'approche simplifiée (fraction de requêtes avec Accept générique/vide), qui est plus robuste et moins coûteuse en calcul ClickHouse.
Utilisation double : Également utilisée par l'axe 3 (HTTP Modern) dans
browser.py (condition generic_accept_ratio < 0.3, poids 0.10).
Références
- Nikiforakis et al. (2013) — Cookieless Monster
- Acar et al. (2014) — The Web Never Forgets
B7 — HTTP/TLS Protocol Version Mismatch
✅ IMPLÉMENTÉ
Feature : http10_ratio — dans FEATURES (les deux modèles).
Note : La proposition originale contenait deux features (http1_tls13_ratio
et http10_ratio). Seule http10_ratio (fraction de requêtes HTTP/1.0) a été
implémentée — c'est le signal le plus fort car HTTP/1.0 est extrêmement rare dans
le trafic navigateur moderne.
Utilisation double : Également utilisée par l'axe 5 (TLS/TCP Coherence) dans
browser.py (condition http10_ratio = 0, poids 0.15).
B8 — IP DF-Bit Consistency
✅ IMPLÉMENTÉ
Feature : ip_df_variance — dans FEATURES_COMPLET (modèle Complet uniquement).
Implémentation : varPop(toFloat64(ip_meta_df)) dans la vue ClickHouse.
La variance du bit DF est combinée avec les features TTL (avg_ttl, ttl_std)
pour le TCP fingerprinting multi-dimensionnel.
B9 — IP DF-Bit Consistency (proposition distincte)
🔄 PARTIEL
État : Couvert par B8. La proposition B9 était une variante de B8 avec une
analyse de cohérence intra-session supplémentaire. Cette variante n'a pas été
implémentée séparément — ip_df_variance couvre le cas d'usage principal.
B10 — JA4 Concentration intra-ASN
✅ IMPLÉMENTÉ (préexistant)
Feature : ja4_asn_concentration — dans FEATURES (les deux modèles).
Note : Cette feature existait déjà avant les propositions B, dans la liste initiale des features du modèle. Elle mesure la concentration d'un même fingerprint JA4 au sein d'un ASN — un JA4 très concentré dans un seul ASN suggère un outil déployé dans un datacenter spécifique.
Récapitulatif des modifications ClickHouse réalisées
Colonnes ajoutées dans agg_host_ip_ja4_1h
Les colonnes suivantes ont été ajoutées au MV et à la table d'agrégation pour supporter les features B1–B8 :
-- B1 : JA3 diversity ratio
uniq_ja3 AggregateFunction(uniq, String)
-- B2 : SYN timing regularity
avg_syn_ms SimpleAggregateFunction(avg, Float64)
-- B3 : TLS 1.2 ratio
tls12_count SimpleAggregateFunction(sum, UInt64)
-- B4 : HEAD method ratio
count_head SimpleAggregateFunction(sum, UInt64)
-- B5 : Sec-Fetch absence
count_no_sec_fetch SimpleAggregateFunction(sum, UInt64)
-- B6 : Generic Accept ratio
count_generic_accept SimpleAggregateFunction(sum, UInt64)
-- B7 : HTTP/1.0 ratio
count_http10 SimpleAggregateFunction(sum, UInt64)
-- B8 : DF-bit variance
ip_df_variance (calculé via varPop dans la vue)
Features dérivées dans view_ai_features_1h
| Feature | Formule | Modèle |
|---|---|---|
ja3_diversity_ratio |
uniqMerge(uniq_ja3) / greatest(uniq_ja4, 1) |
Complet |
syn_timing_cv |
sqrt(tcp_jitter_variance) / greatest(avg_syn_ms, 1) |
Complet |
tls12_ratio |
tls12_count / greatest(hits, 1) |
Complet |
head_ratio |
count_head / greatest(hits, 1) |
Les deux |
sec_fetch_absence_rate |
count_no_sec_fetch / greatest(hits, 1) |
Les deux |
generic_accept_ratio |
count_generic_accept / greatest(hits, 1) |
Les deux |
http10_ratio |
count_http10 / greatest(hits, 1) |
Les deux |
ip_df_variance |
varPop(toFloat64(ip_meta_df)) |
Complet |
Fonctionnalités ajoutées hors propositions initiales
Features et mécanismes implémentés dans la refonte modulaire qui ne figuraient pas dans les propositions A1–A10 / B1–B10 originales.
Ensemble triple-voix (EIF + Autoencoder + XGBoost)
Module : models.py
La proposition initiale n'incluait qu'un Isolation Forest. L'architecture actuelle utilise un ensemble triple-voix :
| Modèle | Poids | Rôle |
|---|---|---|
| Extended Isolation Forest (isotree) | 56% | Détection non supervisée principale |
| Autoencoder (PyTorch) | 24% | Erreur de reconstruction comme signal complémentaire |
| XGBoost | 20% | Supervision via feedback SOC (soc_feedback) |
Formule de combinaison :
final = (1 - β) × [(1 - α) × eif_norm + α × ae_norm] + β × xgb_prob
où α = AE_WEIGHT = 0.30 et β = XGB_WEIGHT = 0.20.
Extended Isolation Forest (isotree)
Module : models.py
Remplacement de sklearn IsolationForest par isotree.ExtendedIsolationForest :
ndim=min(3, len(features))— partitions multi-dimensionnelles (contre 1D pour sklearn)- Calibration des scores :
sklearn_equiv = 0.5 - isotree_score - Fallback automatique vers sklearn si
isotreenon installé
Détection multifactorielle des navigateurs (5 axes)
Module : browser.py
Nouveau système de classification des navigateurs légitimes basé sur 5 axes
pondérés indépendants (voir DOCUMENTATION.md §3.4) :
| Axe | Poids | Signal |
|---|---|---|
| 1 — JA4 Known | 0.25 | Famille navigateur identifiée |
| 2 — JA4 Structure | 0.15 | TLS 1.3, h2/h3, ciphers/extensions |
| 3 — HTTP Modern | 0.25 | Sec-Fetch, Accept-Language, modern_browser_score |
| 4 — Nav Behavior | 0.15 | Cookies, Referer, assets, navigation |
| 5 — TLS Coherence | 0.20 | ALPN, window scale, TLS 1.2 ratio |
Seuil : browser_confidence ≥ 0.55 + famille identifiée → LEGITIMATE_BROWSER.
Escalade de campagne
Module : pipeline.py lignes 311–324
Après le clustering HDBSCAN, les IPs appartenant à un cluster de ≥ 5 membres
voient leur threat level escaladé de HIGH → CRITICAL. Identifie les campagnes
de botnet coordonnées.
Feedback SOC (apprentissage supervisé)
Module : cycle.py lignes 221–238
Intégration du feedback des analystes SOC depuis la table audit_logs :
- Faux positifs (FP) → reclassés en baseline humaine (
asn_label='isp') - Vrais positifs (TP) → étiquetés
soc_confirmed_botpour l'entraînement XGBoost - Configurable via
ENABLE_FEEDBACK=trueetFEEDBACK_WINDOW_DAYS=7
Features thèse §5
Module : preprocessing.py + cycle.py
9 features issues de la thèse (§5) enrichies depuis view_thesis_features_1h :
seq_emb_0..seq_emb_31— embeddings séquentiels via SessionTransformer (§5.2, remplace path_transition_entropy + cadence_cv)burst_ratio/pause_ratio— ratios de rafales et pauseslag1_autocorrelation— autocorrélation lag-1 des inter-arrivéesbenford_deviation— déviation par rapport à la loi de Benfordhost_diversity/host_sweep_speed/host_coverage_uniformity
Features P0+P1 (sous-exploitées et nouvelles)
Module : preprocessing.py
Features supplémentaires ajoutées à FEATURES :
is_fake_navigation— détection de fausse navigation (P0)true_window_size/window_mss_ratio— TCP window analysis (P0, Complet)has_xff— présence de X-Forwarded-For (P1)unusual_content_type_ratio— Content-Types inhabituels (P1)non_standard_port_ratio— ports non standard (P1)login_post_concentration— concentration de POST sur login (P1)sec_ch_mobile_mismatch— incohérence Sec-CH-UA-Mobile (P1)
TTL Fingerprinting OS
Module : preprocessing.py — FEATURES_COMPLET
Features TCP ajoutées pour le fingerprinting du système d'exploitation :
avg_ttl— TTL moyen (différent par OS : 64 Linux, 128 Windows, 255 Cisco)ttl_std— écart-type du TTL (doit être ~0 pour un trafic homogène)no_window_scale_ratio— ratio de sessions sans TCP window scaling
Dérive JA4 intra-session
Module : preprocessing.py — FEATURES_COMPLET
ja4_drift_ratio— fraction de sessions où le JA4 change pendant la session. Signal de bot qui reconfigure son client TLS à chaque requête.
Validation gate (modèles)
Module : models.py
Après entraînement, le modèle est validé sur un jeu de validation (split 80/20).
Si val_anomaly_rate > 0.20, le modèle est rejeté et l'ancien modèle est conservé.
Empêche le déploiement de modèles dégénérés.
Feature pruning automatique
Module : models.py
Les features avec variance < 1e-6 sont automatiquement éliminées avant l'entraînement de l'EIF. Évite les partitions dégénérées sur des features constantes.